Joi.custom()验证器未提供字段时不执行的问题及最佳方案咨询
Joi条件验证问题:自定义验证器未触发的解决方案
需求
对象包含两个属性:
- 数字类型的
firstField - 字符串类型的
secondField
验证规则:
firstField始终为必填项secondField需根据firstField与验证上下文(validation context)中的变量判断:满足条件时必填,不满足时禁用。
当前问题
用Joi.custom()编写secondField的自定义验证逻辑,但输入仅包含firstField时,该自定义验证器不会执行。
已尝试方案
- 提供
secondField时,验证器可正常运行 - 改用
.when()时,即便secondField未提供也能触发规则判断 - 尝试在
custom()前添加.when("firstField", { is: Joi.any(), then: Joi.any(), otherwise: Joi.any()}),无效
最优解决方法
推荐直接用.when()结合上下文变量实现,这是最贴合Joi原生设计的方案,既能覆盖字段存在/缺失的场景,代码也更简洁可维护。
示例代码
const schema = Joi.object({ firstField: Joi.number().required(), secondField: Joi.string() .when(Joi.ref('firstField'), { is: (value, helpers) => { // 结合firstField值与上下文变量判断条件 const contextValue = helpers.prefs.context?.targetVariable; return value > 10 && contextValue === 'required'; // 示例判断条件 }, then: Joi.required(), // 满足条件时必填 otherwise: Joi.forbidden() // 不满足时禁用(输入中不能出现该字段) }) });
为什么不选custom()?
Joi的custom()默认只在字段存在于输入时执行,因为它的设计目标是针对字段值做验证。如果要强制让它在字段缺失时触发,需要额外做复杂配置,远不如.when()直观高效。
字段级处理VS父对象处理?
优先在字段本身通过.when()处理,规则和字段绑定,逻辑清晰易读。只有当条件涉及多个字段的复杂联动,或者需要修改整个对象的验证逻辑时,才考虑在父对象层面处理。
内容的提问来源于stack exchange,提问作者juliushuck
相关产品推荐
相关产品推荐

