Error trying to reuse inferred type
mauroviniciussilva opened this issue · 1 comments
I'm trying to use a type inferred from a zod schema, but when I need to reuse the inferred type in other generic function I just couldn't find a way of doing it.
Considering the following code:
import { z } from 'zod';
const Schema = z.object({
id: z.number(),
name: z.string(),
nickname: z.string().optional().default('')
});
export type SchemaDto = z.infer<typeof Schema>;
const parsedSchema: z.Schema<SchemaDto> = Schema;
I got the following error:
Type 'ZodObject<{ id: ZodNumber; name: ZodString; nickname: ZodDefault<ZodOptional<ZodString>>; }, "strip", ZodTypeAny, { ...; }, { ...; }>' is not assignable to type 'ZodType<{ name: string; id: number; nickname: string; }, ZodTypeDef, { name: string; id: number; nickname: string; }>'.
The types of '_input.nickname' are incompatible between these types.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
I can understand that the inferred type assumed that, once I have the default ''
the field wouldn't be undefined in the generated type:
type SchemaDto = {
name: string;
id: number;
nickname: string;
}
But, if I need to use the generated type to force the usage of a Schema that is compatible with a type, I cannot use the inferred type to accomplish my goal.
In the documentation there's no information on how to infer a type without considering the default
to be able to reuse the inferred type in other generic functions. Is this a relevant functionality to the package?
Hi @mauroviniciussilva that's correct, I looked into the documentation and found .input
.
To work around this and get the input type (before defaults are applied), you can use z.input<typeof Schema>
instead of z.infer
. This will preserve the optionality of nickname, so it’s typed as string | undefined
, matching what you need for your generic function.
This is what your code would look like:
import { z } from 'zod';
const Schema = z.object({
id: z.number(),
name: z.string(),
nickname: z.string().optional().default('')
});
type SchemaInput = z.input<typeof Schema>; // nickname will be string | undefined
const parsedSchema: z.ZodType<SchemaInput> = Schema;