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

如何为异步封装请求函数标注返回类型,让useQuery自动推导类型

解决useQuery返回data类型为any的问题

你的核心问题在于当前的asyncWrapper没有利用TypeScript的泛型传递函数的参数和返回类型信息,导致TypeScript无法推导getQuestions的具体返回类型,最终useQuery的data只能是any。下面是具体的修复步骤:

1. 将asyncWrapper改为泛型函数

我们需要让包装器能够捕获传入处理函数的参数类型和返回类型,这样TypeScript就能完整追踪类型信息:

// 泛型版本的异步包装器
export const asyncWrapper = <TArgs = unknown, TResult = unknown>(
  handler: (args?: TArgs) => Promise<TResult>
) => {
  return async (args?: TArgs): Promise<TResult> => {
    try {
      const result = await handler(args);
      return result;
    } catch (err: any) {
      // 添加可选链避免err.response不存在时报错
      if (err.response?.status === 401) {
        await sessionService.refreshToken();
        // 刷新令牌后重试请求
        const result = await handler(args);
        return result;
      }
      // 必须抛出非401的错误,否则useQuery无法感知请求失败
      throw err;
    }
  };
};

这里的泛型TArgs代表处理函数的参数类型,TResult代表处理函数的返回类型,默认值设为unknown是为了保持兼容性。

2. 修正QuestionsType的类型定义

注意你原来的QuestionsType中answerOptions应该是数组类型(一个问题会对应多个选项),否则返回的数组数据会和类型不匹配:

export type QuestionsType = {
  answerOptions: {
    _id: string;
    answerText: string;
    isCorrect: boolean;
  }[]; // 添加数组标记
  questionText: string;
};

3. 优化getQuestions的定义

现在不需要手动指定getQuestions的返回类型,TypeScript会通过泛型自动推导。同时给axios的get请求指定响应数据类型,确保response.data的类型准确:

const getQuestions = asyncWrapper(async (difficulty: string) => {
  const token = localStorage.getItem("accessToken");

  try {
    // 给axios.get指定响应类型为QuestionsType[]
    const response = await axios.get<QuestionsType[]>("/questions", {
      headers: {
        Authorization: token,
      },
      params: { difficulty } // 假设需要将difficulty作为查询参数传递
    });

    return response.data;
  } catch (e) {
    throw new Error("Custom");
  }
});

4. 验证useQuery的类型推导

现在使用useQuery时,data会自动推导为QuestionsType[] | undefined(undefined是因为useQuery初始状态或请求失败时data可能为空):

// data类型自动推导为QuestionsType[] | undefined
const { data } = useQuery(["quiz", "easy"], () => getQuestions("easy"));

额外注意点

  • 不要忘记在asyncWrapper的catch块中抛出非401的错误,否则useQuery会误判请求成功,无法触发错误状态。
  • 如果你的getQuestions不需要参数,可以将泛型TArgs设为void,或者直接不传参数。

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:05:19