Zod中同时使用optional()与default()时类型推断异常咨询
问题解答
这是Zod的设计意图,核心原因是Zod严格区分了「输入类型」和「输出类型」:
optional()是对输入的约束,允许字段不存在或为undefined;default()是解析阶段的逻辑,仅在调用parse()/safeParse()时,自动为缺失/undefined的字段填充默认值。
z.infer<T>默认返回的是输入类型,所以会保留undefined的可能性。
解决方法
1. 正确使用z.output获取解析后类型
你之前尝试z.output没生效,大概率是用法有误。正确写法如下:
import { z } from "zod"; const PaginationSchema = z.object({ page: z.number().optional().default(1), }); // 输入类型:允许page为 number | undefined type PaginationInput = z.input<typeof PaginationSchema>; // 输出类型:解析后page必然是 number(无undefined) type PaginationOutput = z.output<typeof PaginationSchema>;
当你调用PaginationSchema.parse()时,返回值的类型就是PaginationOutput,page字段一定存在且为数字。
2. 调整Schema定义(可选)
如果不需要输入阶段允许undefined,可以去掉optional(),直接用default():
const PaginationSchema = z.object({ page: z.number().default(1), }); // 输入输出类型一致:{ page: number }(输入时不传page,解析后自动填充1) type PaginationType = z.infer<typeof PaginationSchema>;
这种写法下,输入时如果显式传入undefined会触发校验错误,适合要求输入要么不传、要么传合法数字的场景。
替代工具
如果觉得Zod的输入输出类型区分过于繁琐,可以考虑Valibot——它的类型推断会直接反映默认值的效果,无需额外区分输入输出:
import { object, number, optional, defaultTo } from 'valibot'; const PaginationSchema = object({ page: optional(number(), defaultTo(1)), }); // 推断出的类型直接是 { page: number } type PaginationType = typeof PaginationSchema['type'];
内容的提问来源于stack exchange,提问作者Diyan Slavov
相关产品推荐
相关产品推荐

