You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript如何为react-query的useMutation onError配置泛型类型?

问题原因

  1. 泛型声明位置不匹配:你将泛型T定义在useSignUp hook的调用层级,调用useSignUp()时没有传递任何可用于推导T类型的参数,TypeScript 只能将T fallback 到你定义的约束类型string,最终得到的ErrorResponse自然就是ErrorResponse<string>。
  2. 执行时序限制: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:39:03