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

ReactQuery + TypeScript:如何为Query添加类型?为何出现TS错误?

ReactQuery + TypeScript 类型定义实操方案

1. 直接给useQuery加泛型

useQuery支持三个泛型参数,依次是返回数据类型、错误类型、可选的选择器返回类型,直接指定就能解决类型推断问题:

// 先定义接口描述数据结构
interface User {
  id: number;
  name: string;
  email: string;
}

// 调用useQuery时明确泛型
const { data, error, isLoading } = useQuery<User, Error>(
  ['user', userId],
  () => fetch(`/api/users/${userId}`).then(res => res.json())
);

如果请求可能返回null/undefined,把类型写成User | null即可。

2. 给查询函数单独加类型

如果查询函数会复用,直接给函数指定返回值类型,useQuery会自动推断:

interface Post {
  id: number;
  title: string;
  content: string;
}

// 给fetchPost指定返回Promise<Post>
const fetchPost = async (postId: number): Promise<Post> => {
  const res = await fetch(`/api/posts/${postId}`);
  if (!res.ok) throw new Error('获取文章失败');
  return res.json();
};

// 这里不用额外加泛型,TypeScript能自动识别返回类型
const { data } = useQuery(['post', postId], () => fetchPost(postId));

3. 自定义错误类型

如果后端返回特定格式的错误,也可以给错误加类型:

interface ApiError {
  message: string;
  code: number;
}

const { error } = useQuery<User, ApiError>(
  ['user', userId],
  async () => {
    const res = await fetch(`/api/users/${userId}`);
    if (!res.ok) {
      const errData = await res.json();
      throw errData as ApiError;
    }
    return res.json();
  }
);

// 此时error会被推断为ApiError | null,能直接访问code和message
if (error) {
  console.log(error.code, error.message);
}

4. 用select时指定类型

如果用了select选项处理返回数据,可以通过第三个泛型参数指定处理后的类型:

// 第三个泛型string就是select返回的类型
const { data: userName } = useQuery<User, Error, string>(
  ['user', userId],
  () => fetch(`/api/users/${userId}`).then(res => res.json()),
  {
    select: (user) => user.name
  }
);
// userName的类型是string | undefined

针对你截图的问题总结

你遇到的类型错误基本都是因为TypeScript无法自动推断请求返回的数据结构,只要明确指定泛型参数,把接口定义清楚,就能解决data类型为unknown、无法访问属性这类问题。比如返回数组的场景:

interface Todo {
  id: number;
  text: string;
  completed: boolean;
}

const { data: todos } = useQuery<Todo[], Error>(
  ['todos'],
  () => fetch('/api/todos').then(res => res.json())
);

// 此时todos是Todo[] | undefined,能安全遍历
todos?.forEach(todo => console.log(todo.text));

内容的提问来源于stack exchange,提问作者Wiktor Maciążek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 17:25:23