如何修改Joi对象已有键,实现父子类验证规则继承
解决Joi父子类验证中继承并修改已有规则的问题
我太懂你这个痛点了——在父子类场景用Joi做验证时,想让子类继承父类的基础规则,同时给已有字段加专属限制,但用append()的时候,同名字段直接被覆盖,父类的规则(比如max(10))就丢了对吧?
为什么append()不行?
Joi的append()方法在处理同名键时,是直接替换而非合并规则。你之前的代码里,子类的myArray会完全变成Joi.array().min(1).required(),父类的max(10)限制自然就被覆盖掉了。
两种可行的解决方案
方案一:用concat()+extract()合并规则
通过extract()获取父类字段的完整规则,再叠加子类的限制,最后用concat()合并整个验证对象:
// 声明基类验证对象 const parent = Joi.object({ myArray: Joi.array().max(10) }); // 子类基于父类规则扩展 const child = parent.concat( Joi.object({ foo: Joi.string(), // 提取父类myArray的规则,再添加子类的限制 myArray: parent.extract('myArray').min(1).required() }) );
这样myArray就会同时保留父类的max(10)和子类的min(1).required()规则。
方案二:抽离共用规则变量
把父类和子类共用的字段规则单独抽成变量,子类直接在这个基础上扩展,逻辑更清晰:
// 先抽离myArray的基础规则 const baseMyArrayRule = Joi.array().max(10); // 父类验证规则 const parent = Joi.object({ myArray: baseMyArrayRule }); // 子类基于基础规则添加专属限制,同时新增字段 const child = Joi.object({ foo: Joi.string(), myArray: baseMyArrayRule.min(1).required() });
这种方式复用性更强,后续如果要修改基础规则,只需要改baseMyArrayRule这一处即可。
两种方法最终实现的效果完全符合你的预期:child的myArray规则是array().max(10).min(1).required(),同时还包含新增的foo字段验证。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

