React Hook Form动态设置错误时TypeScript类型报错问题
解决React Hook Form中setError的TypeScript类型错误
问题核心是Object.keys()返回的类型是string[],而setError的第一个参数要求是具体的表单字段联合类型("companyName" | "addressLine"),TypeScript无法自动推断key属于这个联合类型,所以需要手动做类型收窄或断言。
步骤1:定义正确的字段联合类型
直接用keyof从错误对象或表单类型中推导合法字段的联合类型,比自定义Unionize更简洁:
// 方式1:直接声明联合类型 type FormField = "companyName" | "addressLine"; // 方式2:从错误对象类型自动推导(更灵活,修改错误对象时无需手动更新类型) const errors = { "companyName": "Error for companyName", "addressLine": "Error for addressLine" } as const; type FormField = keyof typeof errors;
步骤2:修复setError的类型问题
有两种常用方案:
方案一:类型断言(简单直接)
将key断言为FormField类型,适合你能确定errors的所有键都是合法表单字段的场景:
Object.keys(errors).forEach((key) => { const fieldKey = key as FormField; if (fields.some((field) => field === fieldKey)) { setError(fieldKey, { type: 'custom', message: errors[key] }); } });
方案二:类型守卫(更安全)
编写类型守卫函数,在运行时验证key是否属于合法字段,同时让TypeScript自动收窄类型:
function isFormField(key: string): key is FormField { return ['companyName', 'addressLine'].includes(key); } Object.keys(errors).forEach((key) => { if (isFormField(key) && fields.some((field) => field === key)) { setError(key, { type: 'custom', message: errors[key] }); } });
为什么你的Unionize类型无效?
你定义的Unionize返回的是一个对象类型(比如{companyName: "companyName", addressLine: "addressLine"}),而不是你需要的字段联合类型。正确的联合类型应该直接用keyof T,比如:
type Props = keyof { companyName: string; addressLine: string }; // Props 等价于 "companyName" | "addressLine"
内容的提问来源于stack exchange,提问作者Alexander Zeitler
相关产品推荐
相关产品推荐

