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

Joi验证:如何按需设置字段可选及解决dtcomplete必填报错问题

解决Joi验证中dtcomplete的可选校验问题

这个问题我之前处理过,核心原因是你的dtcomplete字段的when规则在taskstatus不存在时,没有明确定义“非满足条件”下的行为,导致Joi错误地触发了必填校验(可能是版本差异或默认规则的隐性影响)。下面给你两种针对性的解决方案:

方案1:完善dtcomplete的when规则(推荐)

给dtcomplete添加otherwise分支,明确当taskstatus不是'C'/'I'或者不存在时,该字段为可选:

joiSchema = Joi.object().keys({ 
  taskno: Joi.string().alphanum().required().uppercase().trim(), 
  taskstatus: Joi.valid('G', 'C', 'I', 'S'), 
  taskpriority: Joi.number().integer().max(5).min(1), 
  stuckreason: Joi.string().allow('').max(200).trim(), 
  dttarget: Joi.date().iso(), 
  dtdue: Joi.date().iso(), 
  dtcomplete: Joi.when('taskstatus', { 
    is: Joi.valid('C', 'I'), 
    then: Joi.date().iso().required(), 
    otherwise: Joi.optional() // 明确非满足条件时可选
  }) 
});

或者更简洁地把optional()放在前面,让默认行为就是可选,仅在满足条件时转为必填:

dtcomplete: Joi.optional().when('taskstatus', {
  is: Joi.valid('C', 'I'),
  then: Joi.date().iso().required()
})

方案2:只校验需要的字段

既然你的对象仅包含taskno、dttarget和dtdue,可以直接使用Joi的pick()方法筛选出需要校验的字段,完全忽略其他字段的规则:

// 只校验指定字段
const validationResult = joiSchema.pick(['taskno', 'dttarget', 'dtdue']).validate(yourObject);

这种方法最直接,适合你只需要校验部分字段的场景。

补充说明

如果还是报错,建议检查你的Joi版本——不同版本的when规则行为略有差异,升级到最新稳定版(比如v17+)通常能解决这类隐性问题。

内容的提问来源于stack exchange,提问作者beingyogi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:43:42