Impossible to do conditional type with z.$output
or z.$input
?
#5158
-
type MyMeta = { examples: z.$output extends string ? string[] : never };
const myRegistry = z.registry<MyMeta>();
myRegistry.add(z.string(), { examples: ["test"] });
// ^^^Type 'string[]' is not assignable to type 'never' I know |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Your type error occurs because conditional types like So, when you write: type MyMeta = { examples: z.$output extends string ? string[] : never }; You are not passing a schema type to To get the output type of a specific schema (e.g., type MyMeta<T> = { examples: z.$output<T> extends string ? string[] : never };
const myRegistry = z.registry<MyMeta<typeof z.string()>>();
myRegistry.add(z.string(), { examples: ["test"] }); This way, the conditional type will resolve correctly because 📚 Sources: Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
-
You cannot use z.$output as a conditional type directly in a global interface like GlobalMeta. The interface GlobalMeta is not generic and does not receive information about the specific schema type, so TypeScript cannot resolve z.$output to a concrete type at this level(1)(2)(3). If you want per-schema conditional typing (e.g., examples should be string[] for string schemas, number[] for number schemas, etc.), you need to define metadata types locally for each registry or schema, using generics, rather than in a global interface(2)(3). The recommended pattern is to use a generic metadata type with your registry: import * as z from "zod";
type MyMeta<T> = { examples: T extends string ? string[] : never };
const myRegistry = z.registry<MyMeta<z.$output<typeof z.string()>>>();
myRegistry.add(z.string(), { examples: ["test"] }); If you want to extend GlobalMeta for custom fields, you can do so, but you cannot make examples contextually typed per schema instance using only the global interface(1)(3). You can only specify a static type, like examples?: unknown[], in the global interface(1)(3). 📚 Sources: Have another question? Just tag @inkeep. |
Beta Was this translation helpful? Give feedback.
Your type error occurs because conditional types like
z.$output extends string ? string[] : never
do not work as you expect in this context.z.$output
is not a type alias for the output of a specific schema, but rather a generic utility type that requires a type parameter(1)(2). It is meant to be used asz.$output<typeof schema>
, not as a bare type.So, when you write:
You are not passing a schema type to
z.$output
, so TypeScript cannot resolve whatz.$output
is, and the conditional type collapses tonever
(1)(2). That's why assigning astring[]
produces the error.To get the output type of a specific schema (e.g.,
z.…