使用Yup+Formik校验身份证号时遭遇TypeScript类型错误求助
解决Yup+Formik身份证号校验的TypeScript类型错误
错误原因
你的TypeScript报错核心是:Yup的test方法要求校验函数返回值必须是boolean | void | ValidationError | Promise<boolean | ValidationError>,但你自定义的idNumberValidator返回了{status, message}结构的对象,TypeScript无法将其匹配到允许的类型上。
修复步骤
1. 改造身份证号校验函数
将校验函数改为返回校验结果+错误信息的结构,而非自定义状态对象:
export const idNumberValidator = (idNumber: string): { valid: boolean; errorMessage: string } => { if (!idNumber) { return { valid: false, errorMessage: "身份证号不能为空" }; } if (idNumber.length === 12) { // 此处根据实际合法长度调整逻辑 return { valid: true, errorMessage: "" }; } else { return { valid: false, errorMessage: "身份证号格式无效" }; } };
2. 修正Yup的test回调逻辑
注意几个关键问题:
- 原代码存在语法错误(
else if无前置if) - 错误使用了
ownerYup的入参而非表单字段的当前值value - 利用Yup提供的
this.createError生成符合类型要求的校验错误
修正后的ownerYup代码:
import * as yup from "yup"; export const ownerYup = () => // 无需传入idNumber,直接使用表单字段的value yup.object().shape({ idNumber: yup .string() .required("身份证号不能为空") .test( "nationalNumberValidation", "格式错误", // 默认错误信息,会被createError覆盖 function(value) { // 不要用箭头函数,否则无法获取Yup的TestContext if (!value) return false; const { valid, errorMessage } = idNumberValidator(value); if (!valid) { // 生成符合TypeScript类型要求的ValidationError return this.createError({ message: errorMessage, path: "idNumber" }); } return true; // 校验通过返回true } ), });
3. 修正Formik初始化代码
移除ownerYup的多余入参:
const formik = useFormik({ enableReinitialize: true, initialValues: { idNumber, }, validationSchema: ownerYup(), onSubmit: () => {}, });
额外提示
- 不要用箭头函数作为
test的回调,否则无法获取Yup提供的TestContext(包含createError等关键方法) - 如果需要异步校验,直接返回
Promise<boolean | ValidationError>即可 - 可将字段长度判断逻辑整合到
idNumberValidator中,保持Yup代码简洁
内容的提问来源于stack exchange,提问作者nstrn_prsh
相关产品推荐
相关产品推荐

