如何让Yup验证器同时支持字符串与数字两种类型?
用Yup实现兼容字符串/数字类型并自动转换为数字的参数校验
核心方案是利用Yup的transform方法在校验前完成类型转换,再配合number()校验确保最终值为数字类型,同时兼容两种输入格式。
基础实现代码
import * as Yup from 'yup'; // 定义校验schema const requestSchema = Yup.object().shape({ targetId: Yup.number() // 先做类型转换:合法字符串转数字,其他情况保留原值让校验报错 .transform((value) => { if (typeof value === 'string' && !isNaN(Number(value))) { return Number(value); } return value; }) // 统一类型错误提示 .typeError('targetId必须是数字或可转换为数字的字符串') .required('targetId为必填参数') });
代码说明
transform是Yup提供的前置转换钩子,会在校验逻辑执行前处理字段值:这里判断输入如果是字符串且能被解析为有效数字,就自动转为Number类型typeError用来覆盖默认的类型错误提示,让字符串/数字不合法时返回统一的提示文案- 后续的
number()校验会确保最终输出的字段值是数字类型,不管输入是原生数字还是合法的数字字符串
处理边界情况(可选)
如果需要排除空字符串、带空格的无效输入,可以优化transform逻辑:
.transform((value) => { if (typeof value === 'string') { const trimmedVal = value.trim(); // 空字符串转为null,配合nullable或required规则处理 if (trimmedVal === '') return null; // 仅转换能解析为有效数字的字符串 if (!isNaN(Number(trimmedVal))) { return Number(trimmedVal); } } return value; })
校验示例
// 合法输入:数字类型 requestSchema.validate({ targetId: 789 }) .then(validatedData => console.log(validatedData.targetId)) // 输出789(数字类型) // 合法输入:数字字符串 requestSchema.validate({ targetId: "1011" }) .then(validatedData => console.log(validatedData.targetId)) // 输出1011(数字类型) // 非法输入:非数字字符串 requestSchema.validate({ targetId: "abc" }) .catch(err => console.log(err.message)) // 输出"targetId必须是数字或可转换为数字的字符串"
内容的提问来源于stack exchange,提问作者Classfield
相关产品推荐
相关产品推荐

