Home > Net >  How to make a generic getter like z.infer<> in Typescript
How to make a generic getter like z.infer<> in Typescript

Time:11-02

I've been learning Typescript for a few months and i started to discover zod recently, and i wonder how to build such a util getter such as z.infer<>, z.input<> or even z.output<>

What i understand is that z is a class that has a getter "method" that takes a generic and it returns a type, but i have no idea of how this works

I tried to replicate it but couldn't figure it out, can someone help?

CodePudding user response:

If we have some class that has a generic type and uses it:

class Validator<T> { validate(value: any): value is T { /* implementation does not matter */ return true; } }

Then we can extract that generic type with infer:

type Infer<V> = V extends Validator<infer T> ? T : never;

You'll be able to use it like this:

const validator = new Validator<string>();

type S = Infer<typeof validator>; // string

This is the basis of Zod creates z.Infer.

Playground

CodePudding user response:

From my quick digging of the source code, these types seem to be defined in helpers/types.ts:

export type TypeOf<T extends ZodType<any, any, any>> = T["_output"];
export type input<T extends ZodType<any, any, any>> = T["_input"];
export type output<T extends ZodType<any, any, any>> = T["_output"];
export type { TypeOf as infer };
// ...
export abstract class ZodType<
  Output = any,
  Def extends ZodTypeDef = ZodTypeDef,
  Input = Output
> {
  readonly _type!: Output;
  readonly _output!: Output;
  readonly _input!: Input;
  readonly _def!: Def;
// ...

That's how you can build them.

  • Related