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

如何在React Query中实现条件返回类型?

问题分析

你当前的useNetworkQuery返回NetworkQueryResult | NetworkMutationResult联合类型,TypeScript无法根据传入的method参数自动窄化返回类型,导致调用时只能访问两种结果的公共属性,无法获取useQuery的refetch、isFetching或useMutation的mutate、isLoading等专属方法。你尝试的条件类型ResultType未生效,核心原因是没有将函数的输入参数与返回类型通过泛型绑定起来。

解决方案

通过泛型参数绑定输入的method类型,让TypeScript能根据传入的HTTP方法精准推断返回类型:

1. 完善条件类型定义

保留你定义的ResultType,确保它与泛型参数关联:

type NetworkQueryResult = UseQueryResult<any, Error>;
type NetworkMutationResult = UseMutationResult<any, Error, void, unknown>;

type ResultType<Method extends NTWRK_METHODS> = 
  Method extends NTWRK_METHODS.GET ? NetworkQueryResult : NetworkMutationResult;

2. 修改useNetworkQuery为泛型函数

让函数接收泛型参数Method,约束props中的method为该泛型类型,返回类型直接使用ResultType<Method>:

export function useNetworkQuery<Method extends NTWRK_METHODS>(
  props: IUseNetworkCallWithClient & { method: Method }
): ResultType<Method> {
  const { queryKey, axiosClient, url, persist, method, params = '' } = props;

  if (method === NTWRK_METHODS.GET) {
    // 用类型断言让TypeScript识别分支返回值匹配泛型类型
    return useQuery({
      queryKey: [queryKey],
      queryFn: async () => {
        const data = await axiosClient.request({
          method: NTWRK_METHODS.GET,
          url: url,
          params: params,
        });
        return data.data;
      },
      enabled: false,
      meta: { persist },
    }) as ResultType<Method>;
  } else {
    return useMutation({
      mutationKey: [queryKey],
      mutationFn: async () => {
        const data = await axiosClient.request({
          method: method,
          url: url,
          data: params,
        });
        return data.data;
      },
      meta: { persist },
    }) as ResultType<Method>;
  }
}

3. 修改makeNetworkCall为泛型函数

同样让它接收泛型参数Method,并传递给useNetworkQuery:

export const makeNetworkCall = <Method extends NTWRK_METHODS>(
  props: IUseNetworkCallWithoutClient & { method: Method }
) => {
  const { method, queryKey, url, persist, params = '' } = props;
  const config = {
    axiosClient,
    queryKey: queryKey,
    method: method,
    url: url,
    persist: persist,
    params: params,
  };

  return useNetworkQuery<Method>(config);
};

4. 调用时的类型推断

现在调用makeNetworkCall时,TypeScript会根据传入的method自动推断返回类型,可正常访问专属方法:

export const useAuthCalls = () => {
  const loginMutation = makeNetworkCall({
    method: NTWRK_METHODS.POST,
    url: '/users',
    queryKey: 'login',
    persist: true,
    params: '',
  });

  const logIn = () => {
    // 可正常调用mutate方法,无类型报错
    loginMutation.mutate();
  };

  return { logIn };
};
关键说明
  • 泛型参数Method将输入的method与返回类型绑定,让TypeScript在编译时就能推断出正确的结果类型。
  • 分支中使用as ResultType<Method>做类型断言,是因为TypeScript无法自动识别条件分支的返回值与泛型的对应关系。
  • 修改后,传入GET方法会得到UseQueryResult,传入其他方法会得到UseMutationResult,可正常访问各自的专属API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 13:27:02