Skip to content

Instantly share code, notes, and snippets.

@benceg
Last active April 20, 2023 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benceg/5f4b6398b9e3ba164d494793808af407 to your computer and use it in GitHub Desktop.
Save benceg/5f4b6398b9e3ba164d494793808af407 to your computer and use it in GitHub Desktop.
Tip: Use Zod for Safety
import settings from "./settings.json";
export interface DataSchema {
title: string;
author?: string;
content: string;
}
type ExpectedResponse =
| { success: true; data: DataSchema }
| { success: false; error: Error };
export const getData = async (): Promise<ExpectedResponse> => {
try {
// settings.endpoint may not be a valid URL.
const response = await fetch(settings.endpoint);
const data = await response.json();
// TypeScript will assume this to be correct, even though
// we could have received any data in lieu of what we expect.
// We might therefore return unusable data.
return { success: true, data: data as DataSchema };
} catch (error) {
return { success: false, error: error as Error };
}
};
import * as z from 'zod';
import settings from './settings.json';
// Declare these schemas as Zod objects rather than interfaces.
const settingsSchema = z.object({
endpoint: z.string().url(),
});
const dataSchema = z.object({
title: z.string(),
author: z.string().optional(),
content: z.string(),
});
export type DataSchema = z.infer<typeof dataSchema>;
type ExpectedResponse =
| { success: true; data: DataSchema }
| { success: false; error: Error; }
// If validation fails in the global scope, our application will
// fail to run and will throw an error detailing any schema mismatches.
settingsSchema.parse(settings);
export const getData = async (): Promise<ExpectedResponse> => {
try {
// We can now rest assured that settings.endpoint is a URL.
const response = await fetch(settings.endpoint);
const data = await response.json();
// We have a guarantee that any data sent alongside { success: true }
// is usable where it is required.
return dataSchema.safeParse(data);
} catch (error) {
return { success: false, error: error as Error };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment