I have a function that fetches different URLs that return JSON and I want to validate the responses using zod.
Is there a better way than this example, without the need to pass the zod schema to every function call? And is there a way to not use the as T
cast?
import * as z from "zod";
// zod schema
const MyResponse = z.strictObject({
key: z.string()
});
// typescript type
type MyResponse = z.infer<typeof MyResponse>;
// function with typescript generics
async function request<T>(schema: z.ZodObject, url: string): Promise<T> {
const response = await fetch(url);
return schema.parse(await response.json()) /*as T*/;
}
// function call
await request<MyResponse>(MyResponse, '/');
function request<T extends z.ZodObject>(schema: T, url: string)
Inferring T from parameter "schema"
You can create request function with "bound" schema:
import * as z from "zod";
function requestFactory<T extends z.ZodObject>(schema: T): ((url: string) => Promise<z.infer<T>>) {
return async (url) => {
const response = await fetch(url);
return schema.parse(await response.json());
};
}
// ---- example -----
const reqMyResponse = requestFactory(z.strictObject({
key: z.string()
}));
const y = await reqMyResponse('/'); // { key: string; }