Search code examples
typescriptzod

Force object type based on an interface


I want to force a Zod type based on a TypeScript interface:

import { z } from 'zod';

interface Foo {
  id: string;
  count: number;
}

                  //👇🏻
const t = z.object<Foo>({
  count: z.number(),
  id: z.string()
})

How can I do it? The code above doesn't work.


Solution

  • You can give t the respective z.ZodType type.

    const t: z.ZodType<Foo> = z.object({
      count: z.number(),
    })
    // Error: Property 'id' is missing in type '{ count: number; }' but required in type 'Foo'
    

    Alternatively, you can use a helper function:

    const schemaForType = <T>() => <S extends z.ZodType<T, any, any>>(arg: S) => {
      return arg;
    };
    
    schemaForType<Foo>()(
      z.object({
        id: z.string(),
        count: z.number(),
      })
    );
    
    schemaForType<Foo>()(
      z.object({
        id: z.string(),
      })
    // ^^^^^^^^^^^^^^^ Error:  Property 'count' is missing in type '{ id: string; }' but required in type 'Foo'.(2345)
    );
    

    Playground