Yup的Infertype对可选字段不生效问题求助
Yup InferType 不识别可选/可空字段的问题解决办法
问题重现
你的Schema定义如下:
const userSchema = yup.object({ name: yup.string().required(), age: yup.number().required().positive().integer(), email: yup.string().email().optional().notRequired(), website: yup.string().url().nullable(), createdOn: yup.date().default(() => new Date()), });
预期通过yup.InferType<typeof userSchema>得到的类型应该包含可选的email和website字段,但实际推断结果中这两个字段并未被标记为可选,同时你的tsconfig已开启strict: true和strictNullChecks: true。
解决方案
1. 调整链式调用顺序并简化可选字段定义
optional()方法已经包含了notRequired()的逻辑,不需要重复调用,且optional()需要放在字段规则的最后,确保类型推断正确。修改email字段:
email: yup.string().email().optional(),
2. 为可空字段添加optional()标记
nullable()仅允许字段值为null,但不会将字段标记为可选(即类型中不会添加?)。如果需要字段既可选又可空,需同时调用nullable()和optional():
website: yup.string().url().nullable().optional(),
3. 确保使用最新版Yup
旧版本的Yup存在类型推断的已知bug,建议升级到最新的v1.x版本,执行以下命令:
npm install yup@latest # 或 yarn add yup@latest
修改后的完整Schema
const userSchema = yup.object({ name: yup.string().required(), age: yup.number().required().positive().integer(), email: yup.string().email().optional(), website: yup.string().url().nullable().optional(), createdOn: yup.date().default(() => new Date()), }); type User = yup.InferType<typeof userSchema>; // 推断结果符合预期: // { // name: string; // age: number; // email?: string | undefined; // website?: string | null | undefined; // createdOn: Date; // }
关键原因说明
- Yup的链式调用顺序直接影响类型推断,
optional()作为标记字段可选性的方法,需要放在所有校验规则之后。 notRequired()仅移除必填校验,但不会修改字段的可选性;optional()则同时完成“移除必填校验”和“标记字段为可选”两个操作。nullable()和optional()是独立的:前者控制值是否可为null,后者控制字段是否为可选(即是否可以省略)。
内容的提问来源于stack exchange,提问作者Muzaffer Kadir Yılmaz
相关产品推荐
相关产品推荐

