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

