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

如何从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:40:31