Joi自定义验证扩展未生效问题排查求助
问题分析与解决方案
你的问题核心是混淆了Joi的自定义类型扩展和规则扩展的写法:
- 你通过
type: 'address'定义了一个全新的自定义类型,但验证逻辑却放在了rules字段下的address规则中——这个规则是用于给现有类型(比如string)添加额外验证的,而非自定义类型本身的验证逻辑。 - 当你调用
joiExtended.address()时,Joi只会使用该类型的base(即string类型)进行基础验证,不会触发rules里的验证逻辑,所以你的console.log和错误永远不会执行。
修正后的代码
将验证逻辑从rules移到扩展对象的顶层validate属性中,这才是自定义类型的验证入口:
const Joi = require('joi') const joiExtended = Joi.extend({ type: 'address', base: Joi.string(), messages: { 'address.invalid': 'invalid', }, // 自定义类型的验证逻辑直接放在顶层validate中 validate(value, helpers) { console.log('Validating address', value) // 测试用:所有输入都失败 return { value, errors: helpers.error('address.invalid') } } }) try { console.log(joiExtended.attempt('x', joiExtended.address())) } catch (err) { console.error(err.message) } console.log(joiExtended.attempt('foo', joiExtended.number()))
执行结果
运行修正后的代码后,会得到预期结果:
- 控制台打印
Validating address x - 抛出
ValidationError: invalid - 数字校验的sanity check依然正常抛出
Error [ValidationError]: "value" must be a number
额外说明
如果你原本想给string类型添加一个address验证规则(而非自定义类型),写法应该是这样:
const joiExtended = Joi.extend({ type: 'string', base: Joi.string(), messages: { 'string.address': 'invalid address', }, rules: { address: { validate: (value, helpers) => { console.log('Validating address rule', value) return { value, errors: helpers.error('string.address') } } } } }) // 使用时需要链式调用.address()规则 joiExtended.attempt('x', joiExtended.string().address())
内容的提问来源于stack exchange,提问作者Madbreaks
相关产品推荐
相关产品推荐

