如何从react-query导入类型定义,为useQuery钩子的options设置类型?
正确封装React Query useQuery并复用类型的方案
核心思路
直接复用@tanstack/react-query(v3版本为react-query)提供的UseQueryOptions类型,通过泛型参数明确数据、错误、查询键的类型,同时排除封装时已固定的配置项(如queryKey、queryFn),既保留完整的options暴露能力,又避免类型冲突。
步骤与代码示例
1. 导入所需类型
确保从官方包导入正确的类型:
import { useQuery, UseQueryOptions, UseQueryResult, QueryKey } from '@tanstack/react-query';
2. 针对特定API的封装(推荐)
以获取用户列表为例,先定义业务数据类型,再封装钩子:
// 定义业务数据类型 interface User { id: number; name: string; } // 底层API请求函数 const fetchUsers = async (): Promise<User[]> => { const res = await fetch('/api/users'); if (!res.ok) throw new Error('获取用户列表失败'); return res.json(); }; // 封装带类型的自定义useQuery钩子 export const useUsersQuery = ( // 排除已固定的queryKey和queryFn,仅暴露其他可配置项 options?: Omit<UseQueryOptions<User[], Error, User[], ['users']>, 'queryKey' | 'queryFn'> ): UseQueryResult<User[], Error> => { return useQuery({ queryKey: ['users'], // 固定查询键 queryFn: fetchUsers, // 固定请求函数 ...options, // 允许用户传入任意useQuery支持的配置,覆盖默认 }); };
使用该钩子时,开发者能获得useQuery全部options的自动补全和类型检查:
// 示例:自定义配置 const { data, isLoading } = useUsersQuery({ enabled: false, // 类型提示生效 refetchOnWindowFocus: true, select: (users) => users.filter(u => u.id > 10) // 自动推导select的参数/返回值类型 });
3. 通用型封装(适用于任意API)
如果需要一个可复用的通用钩子,支持任意queryKey和queryFn:
export function useCustomQuery< TData = unknown, TError = Error, TQueryFnData = TData, TQueryKey extends QueryKey = QueryKey >( queryKey: TQueryKey, queryFn: () => Promise<TQueryFnData>, options?: Omit<UseQueryOptions<TData, TError, TQueryFnData, TQueryKey>, 'queryKey' | 'queryFn'> ): UseQueryResult<TData, TError> { return useQuery({ queryKey, queryFn, ...options, }); }
使用时可自动推导类型,或手动指定泛型:
// 自动推导类型 const { data } = useCustomQuery(['posts'], async () => { const res = await fetch('/api/posts'); return res.json() as { id: number; title: string }[]; }); // 手动指定泛型 const { data } = useCustomQuery<{ id: number; title: string }[], Error>( ['posts'], async () => { const res = await fetch('/api/posts'); return res.json(); }, { refetchInterval: 60000 } );
常见错误排查
之前使用UseQueryOptions出现类型不匹配,通常是以下原因:
- 未正确指定泛型参数(
TData/TError/TQueryKey等) - 未排除封装时已固定的
queryKey/queryFn字段,导致类型冲突 - 版本不兼容:v3版本的
react-query与v4+的@tanstack/react-query类型定义有差异,需对应版本导入
内容的提问来源于stack exchange,提问作者Lukas Liesis
相关产品推荐
相关产品推荐

