You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 01:20:25