如何在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
相关产品推荐
相关产品推荐

