使用Yup时未传oldPassword却触发password必填验证错误
问题分析与解决方案
你遇到的问题是Yup条件验证逻辑未按预期执行,核心原因是简写的.when()语法在处理未定义(不存在)的依赖字段时,容易出现判断逻辑歧义,导致password和confirmPassword被错误标记为必填。
修正后的Schema代码
import * as Yup from 'yup'; const schema = Yup.object().shape({ name: Yup.string(), email: Yup.string().email(), oldPassword: Yup.string().min(6).notRequired(), // 显式标记为非必填 password: Yup.string() .min(6) .notRequired() // 初始标记为非必填 .when('oldPassword', { is: (val) => !!val, // 明确判断oldPassword是否存在且有值 then: (field) => field.required(), otherwise: (field) => field.notRequired() }), confirmPassword: Yup.string() .notRequired() // 初始标记为非必填 .when('password', { is: (val) => !!val, then: (field) => field.required().oneOf([Yup.ref('password')]), otherwise: (field) => field.notRequired() }) });
关键修改点说明
- 显式标记非必填字段:给
oldPassword、password、confirmPassword都加上.notRequired(),明确初始状态为可选,避免Yup默认规则的潜在歧义。 - 改用完整的
.when()语法:放弃简写的回调方式,使用is/then/otherwise结构,清晰定义依赖字段的判断条件和对应验证规则。这种写法在处理依赖字段不存在(undefined)的场景时,逻辑更稳定。 - 明确条件判断逻辑:用
!!val判断依赖字段是否存在且非空,避免直接使用val可能带来的类型判断问题(比如空字符串会被当成false,但这里我们只关心字段是否有提交值)。
验证测试
使用你提供的请求体:
{ "name": "Amanda", "email": "amanda@example.com" }
修正后的Schema会正确跳过password和confirmPassword的必填验证,不会再返回这两个字段的错误。
额外排查方向
如果仍存在问题,可以检查:
- 确保Yup版本是1.0.0的最新补丁版本,避免已知的条件验证bug
- 再次确认
req.body确实未包含oldPassword、password字段(验证前可打印console.log(req.body))
内容的提问来源于stack exchange,提问作者Amanda Alkmim
相关产品推荐
相关产品推荐

