使用Yup .required()时TypeScript未正确推断必填字段类型问题
解决Yup Schema中TypeScript类型推断将必填字段识别为可选的问题
问题场景
我用Yup构建营销活动表单的校验Schema,其中sellers字段是{id: number; label: string}类型的对象数组。但TypeScript推断时,会把数组中对象的id和label识别为可选类型,导致表单类型错误。
我的Yup Schema代码
const validationSchema = yup.object().shape({ sellers: yup .array() .of( yup.object().shape({ id: yup.number().required().defined(), label: yup.string().defined().required(), }), ) .required(), });
期望的TypeScript类型
{ sellers: { id: number; label: string; }[]; }
实际推断的TypeScript类型
{ sellers: { id?: number | undefined; label?: string | undefined; }[]; }
使用环境:TypeScript 5.2.2、Yup 1.3.2,原本以为.required()和.defined()会让TS识别为必填,但没生效,求解决方法。
解决方案
方法1:手动定义目标类型并断言
先明确你需要的类型,再通过类型断言让TS认可Schema的推断结果:
// 手动定义表单值的目标类型 type FormValues = { sellers: { id: number; label: string; }[]; }; // 给Schema添加类型断言,强制TS使用定义好的类型 const validationSchema = yup.object().shape({ sellers: yup .array() .of( yup.object().shape({ id: yup.number().required().defined(), label: yup.string().required().defined(), }), ) .required(), }) as yup.SchemaOf<FormValues>;
方法2:用Yup的InferType结合类型工具修正
如果不想完全手动写类型,可以先获取Yup自动推断的类型,再用TS工具类型把可选字段转为必填:
import { InferType } from 'yup'; const validationSchema = yup.object().shape({ sellers: yup .array() .of( yup.object().shape({ id: yup.number().required().defined(), label: yup.string().required().defined(), }), ) .required(), }); // 定义工具类型:把对象的所有可选字段转为必填 type RequiredFields<T> = { [K in keyof T]-?: T[K] }; // 修正推断出的类型:将数组里的对象转为全必填 type FormValues = { sellers: RequiredFields<InferType<typeof validationSchema>['sellers'][number]>[]; };
方法3:改用strictObject优化类型推断
在Yup 1.x版本中,yup.object()默认允许额外字段,可能干扰TS的类型推断。改用yup.strictObject()可以更严格地约束对象结构,帮助TS更准确识别必填字段:
const validationSchema = yup.object().shape({ sellers: yup .array() .of( yup.strictObject().shape({ id: yup.number().required().defined(), label: yup.string().required().defined(), }), ) .required(), });
内容的提问来源于stack exchange,提问作者Mehmet Emre Ast
相关产品推荐
相关产品推荐

