如何配置Joi.number()使其支持点与逗号作为十进制分隔符?
解决Joi同时支持点和逗号作为十进制分隔符的数值验证问题
要让Joi支持点(.)和逗号(,)两种十进制分隔符,可以通过预处理替换+自定义验证的方式实现,以下是几种实用方案:
方案1:字符串预处理后转数字验证
先接受字符串类型的输入,将逗号替换为点后转为数字,同时保留最终的数值类型:
const schema = Joi.object({ amount: Joi.string() .replace(',', '.') // 将输入中的逗号替换为点 .custom((value, helpers) => { const num = parseFloat(value); if (isNaN(num)) { return helpers.error('any.invalid'); // 转换失败返回错误 } return num; // 验证通过返回数值类型 }) .required() });
方案2:先验证格式再转换
先通过正则确保输入符合合法数字格式(允许整数或带点/逗号的小数),再进行转换验证:
const schema = Joi.object({ amount: Joi.string() .pattern(/^\d+([.,]\d+)?$/) // 匹配整数或带点/逗号的小数格式 .custom((value, helpers) => { const formattedValue = value.replace(',', '.'); const num = Number(formattedValue); if (isNaN(num)) { return helpers.error('any.invalid'); } return num; }) .required() });
方案3:结合Joi.number()的链式规则
如果需要使用Joi.number()的内置验证(比如min、max),可以在转换后继续链式调用:
const schema = Joi.object({ amount: Joi.string() .replace(',', '.') .custom((value, helpers) => { const num = parseFloat(value); return isNaN(num) ? helpers.error('any.invalid') : num; }) .number() // 启用number类型验证规则 .min(0) // 示例:限制数值不小于0 .required() });
以上方案的核心逻辑都是先将逗号分隔的格式统一转为点分隔,再验证数值合法性,最终返回标准的数值类型,同时兼容两种输入格式。
内容的提问来源于stack exchange,提问作者Nicke7117
相关产品推荐
相关产品推荐

