yup InferType推导类型与自定义Person类型不匹配问题
问题原因
yup 1.4.0中,yup.InferType对lazy返回的动态Schema类型推导存在局限——它无法识别不同分支返回的Schema的联合类型,只会取所有分支Schema的类型交集,也就是PersonBase,自然和你期望的Person(PersonBase & (MalePerson | FemalePerson))不一致。
解决方案
方案1:直接复用已定义的Person类型
既然你已经手动定义了符合业务逻辑的Person类型,完全可以直接把PersonSchemaForm指定为这个类型,不需要依赖InferType的自动推导:
// 替换原来的PersonSchemaForm定义 export type PersonSchemaForm = Person;
这种方式简单直接,完全匹配你的业务类型预期。
方案2:用when替代lazy实现条件验证(优化类型推导)
如果希望Schema的类型推导更贴合实际验证逻辑,可以改用yup.when来定义条件字段,这样InferType能更准确识别联合类型:
export const personSchema = yup.object().shape({ name: yup.string().required(), family: yup.string().required(), age: yup.number().required(), gender: yup.string().oneOf(genderValues).required().default(PersonGender.Male), // 针对gender字段添加条件验证 activities: yup .array() .of(yup.string().required()) .min(1) .required() .when('gender', { is: PersonGender.Male, then: schema => schema.required(), otherwise: schema => schema.strip() // 非male时移除该字段 }), characters: yup .array() .of(yup.string().required()) .min(1) .required() .when('gender', { is: PersonGender.Female, then: schema => schema.required(), otherwise: schema => schema.strip() // 非female时移除该字段 }) }) as yup.ObjectSchema<Person>; // 此时InferType的结果会和Person一致 export type PersonSchemaForm = yup.InferType<typeof personSchema>;
这里用strip()在不符合条件时移除对应字段,确保最终结构和Person类型匹配,同时通过类型断言兜底保证类型准确。
方案3:对lazy Schema的推导结果做类型修正
如果坚持使用lazy,可以通过类型断言强制修正InferType的结果:
export const personSchema = yup.lazy((value) => { switch (value.gender) { case PersonGender.Male: return baseSchema.concat(maleSchema); case PersonGender.Female: return baseSchema.concat(femaleSchema); default: return baseSchema; } }) as yup.ObjectSchema<Person>; export type PersonSchemaForm = yup.InferType<typeof personSchema>;
这种方式保留了lazy的动态逻辑,同时让推导类型和Person一致。
内容的提问来源于stack exchange,提问作者Saeed Khazaei
相关产品推荐
相关产品推荐

