Yup数字验证:含逗号与点的输入为何验证表现不同?
Yup非负整数校验的差异问题及解决
问题背景
使用以下Yup校验规则校验非负整数(允许输入0)时,出现了两种不同的校验表现:
const schema = yup.object().shape({ closedBugs: yup .number() .typeError("Please enter a valid number") .integer("Please enter an integer") .required("This field is required") .test( "is-positive", "Please enter a positive number", (value) => value >= 0 && 1 / value !== -Infinity ), });
- 输入
-45.1(含小数点):会收到「请输入整数」「请输入正数」两个提示 - 输入
-45,1(含逗号):仅收到「请输入有效的数字」的提示
差异原因
核心在于Yup的number()类型校验逻辑:
- 对于
-45.1:JavaScript能直接将其解析为合法数字(-45.1),类型校验通过后,会继续执行后续的integer()和自定义is-positive校验,因此触发两个错误提示。 - 对于
-45,1:JavaScript无法识别逗号为小数点分隔符,无法将其解析为有效数字,导致number()的类型校验直接失败,抛出typeError提示,后续校验步骤不会执行,因此只显示一个错误。
解决方案:统一输入处理
通过Yup的transform方法,在类型校验前将输入中的逗号替换为小数点,让两种格式的输入走相同的校验流程:
const schema = yup.object().shape({ closedBugs: yup .number() .transform((value) => { // 处理带逗号的输入,替换为小数点后尝试转数字 if (typeof value === 'string') { const formattedValue = value.replace(',', '.'); return isNaN(Number(formattedValue)) ? value : Number(formattedValue); } return value; }) .typeError("Please enter a valid number") .integer("Please enter an integer") .required("This field is required") .test( "is-positive", "Please enter a positive number", (value) => value >= 0 && 1 / value !== -Infinity ), });
处理后效果:
- 输入
-45,1会被转换为-45.1,通过类型校验后触发integer()和is-positive的错误提示,与-45.1的表现一致; - 无效输入(如
abc)仍会触发「请输入有效的数字」提示,不破坏原有校验逻辑。
内容的提问来源于stack exchange,提问作者mismas
相关产品推荐
相关产品推荐

