TypeScript如何为react-query的useMutation onError配置泛型类型?
问题原因
- 泛型声明位置不匹配:你将泛型
T定义在useSignUphook的调用层级,调用useSignUp()时没有传递任何可用于推导T类型的参数,TypeScript 只能将Tfallback 到你定义的约束类型string,最终得到的ErrorResponse自然就是ErrorResponse<string>。 - 执行时序限制:hook是在组件渲染阶段同步执行的,而
mutate函数是在后续用户交互等异步时机才调用的,TypeScript 无法通过后续mutate调用时传入的参数,反向推断之前hook执行时的泛型类型。
解决方案
方案1:显式传入泛型(最简单)
调用useSignUp的时候直接传入字段的联合类型,即可完成所有类型约束:
// 组件内调用hook时显式指定泛型 const signupMutation = useSignUp<"name" | "email">();
此时:
mutate接收的参数会自动约束为必须包含name和email两个字符串字段onError回调的入参result类型自动推导为ErrorResponse<"name" | "email">- hook内部
reject返回的field如果不在"name" | "email"范围内,TypeScript会直接抛出类型错误
方案2:自动推导泛型(无需手动写联合类型)
如果不想手动写联合类型,可以调整useSignUp的定义,接收字段数组作为入参来自动推导泛型:
// 修改useSignUp定义 export const useSignUp = <T extends string>(fields: T[]) => { return useMutation<SuccessResponse, ErrorResponse<T>, Record<T, string>>( (data) => { return new Promise((resolve, reject) => { // 原有业务逻辑不变 if (Math.random() > 0.5) { resolve({ userId: "1234" }); } else { reject({ formErrors: [ { field: "email", // 非指定字段会触发TS报错 type: "ALREADY_EXISTS" } ] }); } }); } ); };
组件内调用时传入字段数组即可自动推导类型:
// TS自动推导泛型为"name" | "email" const signupMutation = useSignUp(["name", "email"]);
内容的提问来源于stack exchange,提问作者Misha Moroshko
相关产品推荐
相关产品推荐

