无法构建Yup Schema:根据goalType设置goalWeight与weight的大小校验规则
Yup Schema动态校验goalWeight的TypeScript错误修复
需求
构建Yup Schema,根据goalType字段的值动态校验goalWeight:
- 当
goalType为gain时,goalWeight必须大于weight - 当
goalType为LOOSE时,goalWeight必须小于weight
问题代码
object({ weight: number().min(0).max(200).required(), goalType: string().default(GoalType.LOOSE), goalWeight: number() .moreThan(0) .lessThan(200) .required() .when("goalType", { is: GoalType.LOOSE, then: number().lessThan(ref("weight")), }), })
报错信息
No overload matches this call. Overload 1 of 4, '(keys: string | string[], builder: ConditionBuilder<NumberSchema<number, AnyObject, undefined, "">>): NumberSchema<number, AnyObject, undefined, "">', gave the following error. Overload 2 of 4, '(keys: string | string[], options: ConditionConfig<NumberSchema<number, AnyObject, undefined, "">>): NumberSchema<number, AnyObject, undefined, "">', gave the following error.ts(2769) index.d.ts(295, 5): The expected type comes from property 'then' which is declared here on type 'ConditionConfig<NumberSchema<number, AnyObject, undefined, "">>'
错误原因
when方法的then选项不能直接创建新的number()实例,TypeScript要求这里必须是一个接收当前NumberSchema并返回修改后schema的函数,直接新建schema会导致类型不匹配。
修复代码
import * as yup from 'yup'; // 假设GoalType是定义好的枚举/常量 const GoalType = { LOOSE: 'loose', GAIN: 'gain' } as const; const schema = yup.object({ weight: yup.number().min(0).max(200).required(), goalType: yup.string() .default(GoalType.LOOSE) .oneOf(Object.values(GoalType)), // 约束goalType只能是有效值 goalWeight: yup.number() .moreThan(0) .lessThan(200) .required() .when("goalType", { is: GoalType.LOOSE, then: (currentSchema) => currentSchema.lessThan(yup.ref("weight"), '目标体重必须小于当前体重'), otherwise: (currentSchema) => currentSchema.moreThan(yup.ref("weight"), '目标体重必须大于当前体重') }), });
关键修改说明
- 用函数处理
then/otherwise:接收当前的schema实例,链式添加校验规则,确保类型匹配 - 补充
otherwise逻辑:覆盖goalType为gain的场景,完成完整校验逻辑 - 添加
oneOf约束:限制goalType的可选值,避免非法输入导致校验失效
内容的提问来源于stack exchange,提问作者Waldemar Karasik
相关产品推荐
相关产品推荐

