typescripttypescript-genericszod

Parse JSON response with zod inside a TypeScript function that uses Generics


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?

See TypeScript Playground

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, '/');

Solution

  • Playground

    function request<T extends z.ZodObject>(schema: T, url: string)
    

    Inferring T from parameter "schema"

    You can create request function with "bound" schema:

    Playground

    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; }