question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Input schemas defined with Zod does not use the inferred input type

See original GitHub issue

Summary

trpc.router()
  .query('greeting', {
    input: z.object({
      hi: z.string().transform(s => s.length),
    }),
    resolve({ input }) {
      input.hi // => `number`, as expected
    },
  });

// Somewhere else

client.query('greeting', { hi: 'my greeting' }); // => ERROR: expected `number`

CodeSandbox

When defining an input schema using zod, I would expect the call site to accept the z.input version of the schema.

Details

When you define a schema with zod, like this simple one:

const GreetingSchema = z.object({
  hi: z.string(),
});

You can infer its type with z.infer like this:

type Greeting = z.infer<typeof GreetingSchema>;

// Equals

type Greeting = {
  hi: string;
}

However, in zod you can also add transformers that change the type of a field, which means the input and output types of the schema are different.

Here’s an example of that:

const GreetingSchema = z.object({
  hi: z.string().transform(s => s.length),
});

z.infer infers the output type of this:

type InferredGreeting = z.infer<typeof GreetingSchema>;

// Equals

type InferredGreeting {
  hi: number;
}

To get at the input type, zod also has a z.input helper (and z.output, which z.infer is an alias of), meaning you can get at the version we want:

type InputGreeting = z.input<typeof GreetingSchema>;
type OutputGreeting = z.output<typeof GreetingSchema>;

// Equals

type InputGreeting {
  hi: string;
}

type OutputGreeting {
  hi: number;
}

This is also mentioned in the README of Zod.

This concept applied to tRPC:

trpc.router()
  .query('greeting', {
    input: z.object({
      hi: z.string().transform(s => s.length),
    }),
    resolve({ input }) {
      input.hi // => `number`, as expected
    },
  });

// Somewhere else

client.query('greeting', { hi: 'my greeting' }); // => ERROR: expected `number`

In other words, for tRPC I would expect the type required to call a function to be the z.input type, and the type available in the resolve function to be the z.output type.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
KATTcommented, Oct 29, 2021
1reaction
KATTcommented, Oct 29, 2021

Got a working branch in #1189 - just waiting for feedback

Read more comments on GitHub >

github_iconTop Results From Across the Web

Zod: Show inferred nested types in IDE - Stack Overflow
I'm using Zod to define schemas and infer the types from the schemas. I prefer to define a new schema whenever I'm nesting...
Read more >
Schema validation in TypeScript with Zod - LogRocket Blog
In this article, you will learn about schema design and validation in Zod and how to run it in a TypeScript codebase at...
Read more >
Untitled
Otherwise Zod can't correctly infer the types of your schemas! ... takes one input (of type `T` — the inferred type of the...
Read more >
Designing the perfect Typescript schema validation library
You can define a recursive schema in Zod, but because of a limitation of Typescript, their type can't be statically inferred. If you...
Read more >
/README.md | zod@v3-snapshot-2021-01-21 | Deno
The first is the validation function. This function takes one input (of type T — the inferred type of the schema) and returns...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found