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
相关产品推荐
相关产品推荐

