React升级后Yup自定义验证及when条件TypeScript报错求助
依赖升级后Yup+TypeScript报错解决方案
问题1:自定义Yup方法birthdate不存在于ObjectSchema类型
错误信息
Property 'birthdate' does not exist on type 'ObjectSchema<{ year: string; month: string; day: string; }, AnyObject, { year: undefined; month: undefined; day: undefined; }, "">'.ts(2339)
解决步骤
- 移除冲突的类型依赖
Yup 1.x版本已内置TypeScript类型定义,无需额外安装@types/yup。你的项目中同时存在yup@1.2.0和@types/yup@0.29.11会导致类型冲突,执行命令卸载旧类型包:
npm uninstall @types/yup # 或 yarn remove @types/yup
- 扩展Yup的ObjectSchema类型
在validations.ts文件顶部添加类型声明,让TypeScript识别自定义的birthdate方法:
import * as yup from 'yup'; // 扩展Yup类型,添加birthdate方法 declare module 'yup' { interface ObjectSchema<T, C = yup.AnyObject, O = T, M = yup.Maybe<T>> { birthdate(): ObjectSchema<T, C, O, M>; } } // 你的自定义方法代码 yup.addMethod(yup.object, 'birthdate', function () { return this.test( 'birthdate', i18n.t('validations:separated_date'), (value) => { if (value.year < 1900) return false; const date = `${value.day}/${value.month}/${value.year}`; const today = moment(); const momentDate = moment(date, 'DD/MM/YYYY', true); return today.isAfter(momentDate); }, ); });
问题2:Yup.when配置中is属性类型不匹配
错误信息
No overload matches this call. Overload 1 of 4, '(keys: string | string[], builder: ConditionBuilder<StringSchema<string | undefined, AnyObject, undefined, "">>): StringSchema<string | undefined, AnyObject, undefined, "">', gave the following error. Argument of type '{ is: (birthdateNow: SeparatedDate) => boolean | ""; otherwise: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">; then: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">; }' is not assignable to parameter of type 'ConditionBuilder<StringSchema<string | undefined, AnyObject, undefined, "">>'. Object literal may only specify known properties, and 'is' does not exist in type 'ConditionBuilder<StringSchema<string | undefined, AnyObject, undefined, "">>'.ts(2769)
解决步骤
Yup 1.x重构了when方法的API,不再支持is/then/otherwise的对象式配置,改为使用函数式构建器。调整代码如下:
legalGuardianEmail: yup.string().when('birthdate', (schema, { parent }) => { const birthdateNow = parent.birthdate as SeparatedDate; const hasLegalAge = checkIfOlderThan(birthdateNow, USER_LEGAL_AGE); // 根据条件返回对应的schema规则 if (birthdateNow.day && !hasLegalAge) { return schema .trim() .lowercase() .email() .notOneOf([formValues.email], 'validations:same_email') .required() .validEmail(); } else { return schema.transform(() => ''); } }),
关键说明
- 函数式构建器接收当前schema和上下文参数,通过上下文的
parent属性可获取表单其他字段值 - 无需单独声明
is条件,直接在函数内部判断并返回对应schema规则即可 - 若需依赖多个字段,可将第一个参数改为字符串数组(如
['birthdate', 'anotherField'])
内容的提问来源于stack exchange,提问作者Ala Ha
相关产品推荐
相关产品推荐

