📄 tanstack/query/v4/docs/framework/vue/typescript

File: typescript.md | Updated: 11/15/2025

Source: https://tanstack.com/query/v4/docs/framework/vue/typescript



TanStack

Query v4v4

Search...

+ K

Auto

Log In

TanStack StartRC

Docs Examples GitHub Contributors

TanStack Router

Docs Examples GitHub Contributors

TanStack Query

Docs Examples GitHub Contributors

TanStack Table

Docs Examples Github Contributors

TanStack Formnew

Docs Examples Github Contributors

TanStack DBbeta

Docs Github Contributors

TanStack Virtual

Docs Examples Github Contributors

TanStack Paceralpha

Docs Examples Github Contributors

TanStack Storealpha

Docs Examples Github Contributors

TanStack Devtoolsalpha

Docs Github Contributors

More Libraries

Maintainers Partners Support Learn StatsBETA Discord Merch Blog GitHub Ethos Brand Guide

Documentation

Framework

Vue logo

Vue

Version

v4

Search...

+ K

Menu

Getting Started

Guides & Concepts

Community Resources

API Reference

ESLint

Examples

Framework

Vue logo

Vue

Version

v4

Menu

Getting Started

Guides & Concepts

Community Resources

API Reference

ESLint

Examples

On this page

TypeScript

Copy Markdown

Vue Query is now written in TypeScript to make sure the library and your projects are type-safe!

Things to keep in mind:

  • Types currently require using TypeScript v4.1 or greater
  • Changes to types in this repository are considered non-breaking and are usually released as patch semver changes (otherwise every type enhancement would be a major version!).
  • It is highly recommended that you lock your vue-query package version to a specific patch release and upgrade with the expectation that types may be fixed or upgraded between any release
  • The non-type-related public API of Vue Query still follows semver very strictly.

Type Inference
--------------

Types in Vue Query generally flow through very well so that you don't have to provide type annotations for yourself

tsx

const { data } = useQuery({
  //    ^? const data: Ref<number> | Ref<undefined>
  queryKey: ['test'],
  queryFn: () => Promise.resolve(5),
})


const { data } = useQuery({
  //    ^? const data: Ref<number> | Ref<undefined>
  queryKey: ['test'],
  queryFn: () => Promise.resolve(5),
})

typescript playground

tsx

const { data } = useQuery({
  //      ^? const data: Ref<string> | Ref<undefined>
  queryKey: ['test'],
  queryFn: () => Promise.resolve(5),
  select: (data) => data.toString(),
})


const { data } = useQuery({
  //      ^? const data: Ref<string> | Ref<undefined>
  queryKey: ['test'],
  queryFn: () => Promise.resolve(5),
  select: (data) => data.toString(),
})

typescript playground

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: Ref<Group[]> | Ref<undefined>


const fetchGroups = (): Promise<Group[]> =>
  axios.get('/groups').then((response) => response.data)

const { data } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
//      ^? const data: Ref<Group[]> | Ref<undefined>

typescript playground

Type Narrowing
--------------

Vue 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 } = reactive(
  useQuery({
    queryKey: ['test'],
    queryFn: () => Promise.resolve(5),
  }),
)

if (isSuccess) {
  data
  // ^? const data: number
}


const { data, isSuccess } = reactive(
  useQuery({
    queryKey: ['test'],
    queryFn: () => Promise.resolve(5),
  }),
)

if (isSuccess) {
  data
  // ^? const data: number
}

typescript playground

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: Ref<unknown>

if (error.value instanceof Error) {
  error.value
  //     ^? const error: Error
}


const { error } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups })
//      ^? const error: Ref<unknown>

if (error.value instanceof Error) {
  error.value
  //     ^? const error: Error
}

typescript playground

Edit on GitHub

Devtools

GraphQL

Partners Become a Partner

Code RabbitCode Rabbit CloudflareCloudflare AG GridAG Grid NetlifyNetlify NeonNeon WorkOSWorkOS ClerkClerk ConvexConvex ElectricElectric SentrySentry PrismaPrisma StrapiStrapi UnkeyUnkey

[###### 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

scarf analytics