File: typescript.md | Updated: 11/15/2025
Search...
+ K
Auto
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Maintainers Partners Support Learn StatsBETA Discord Merch Blog GitHub Ethos Brand Guide
Documentation
Framework
React
Version
v4
Search...
+ K
Menu
Getting Started
Guides & Concepts
Community Resources
API Reference
ESLint
Plugins
Examples
Framework
React
Version
v4
Menu
Getting Started
Guides & Concepts
Community Resources
API Reference
ESLint
Plugins
Examples
On this page
Copy Markdown
React Query is now written in TypeScript to make sure the library and your projects are type-safe!
Things to keep in mind:
Types in React Query generally flow through very well so that you don't have to provide type annotations for yourself
tsx
const { data } = useQuery({
// ^? const data: number | undefined
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
})
const { data } = useQuery({
// ^? const data: number | undefined
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
})
tsx
const { data } = useQuery({
// ^? const data: string | undefined
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
})
const { data } = useQuery({
// ^? const data: string | undefined
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
})
This works best if your queryFn has a well-defined returned type. Keep in mind that most data fetching libraries return any per default, so make sure to extract it to a properly typed function:
tsx
const fetchGroups = (): Promise<Group[]> =>
axios.get('/groups').then((response) => response.data)
const { data } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const data: Group[] | undefined
const fetchGroups = (): Promise<Group[]> =>
axios.get('/groups').then((response) => response.data)
const { data } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const data: Group[] | undefined
React Query uses a discriminated union type for the query result, discriminated by the status field and the derived status boolean flags. This will allow you to check for e.g. success status to make data defined:
tsx
const { data, isSuccess } = useQuery({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
})
if (isSuccess) {
data
// ^? const data: number
}
const { data, isSuccess } = useQuery({
queryKey: ['test'],
queryFn: () => Promise.resolve(5),
})
if (isSuccess) {
data
// ^? const data: number
}
Typing the error field
----------------------
The type for error defaults to unknown. This is in line with what TypeScript gives you per default in a catch clauses (see useUnknownInCatchVariables ). The safest way to work with error would be to perform a runtime check; another way would be to explicitly define types for data and error:
tsx
const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const error: unknown
if (error instanceof Error) {
error
// ^? const error: Error
}
const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
// ^? const error: unknown
if (error instanceof Error) {
error
// ^? const error: Error
}
tsx
const { error } = useQuery<Group[], Error>(['groups'], fetchGroups)
// ^? const error: Error | null
const { error } = useQuery<Group[], Error>(['groups'], fetchGroups)
// ^? const error: Error | null
Further Reading
---------------
For tips and tricks around type inference, have a look at React Query and TypeScript from the Community Resources. To find out how to get the best possible type-safety, you can read Type-safe React Query .
[###### Want to Skip the Docs?
Query.gg - The Official React Query Course
\
“If you’re serious about *really* understanding React Query, there’s no better way than with query.gg”—Tanner Linsley
Learn More](https://query.gg/?s=tanstack)
You are currently reading v4 docs. Redirect to latest version?
Latest Hide
