TanStack / TanStack/query

Branded queryKey in queryOptions causes TS error (TS2769) in useQuery

Open
#9,920 3 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

package: vue-query
Dominant language
TypeScript
Stars
50.3k
Forks
4.2k
Avg merge
18h 25m
Merged PRs (30d)
200

Description

Describe the bug

I’m encountering a TypeScript overload mismatch (TS2769) when calling useQuery() with the result of a queryOptions(...) function whose returned object contains a queryKey with a branded type. The error occurs specifically when useQuery() receives the output of queryOptions(...) containing a branded value in queryKey.

Passing the same options to queryClient.fetchQuery(queryOptions(queryKey: brandedKey, queryFn)) — works fine.
Passing the branded key inline to useQuery (i.e. useQuery({ queryKey: brandedKey, queryFn})) — works fine.

Your minimal, reproducible example

https://codesandbox.io/p/devbox/tanstack-query-ts-error-2769-forked-spc8jh?file=%2Fsrc%2FPost.vue

Steps to reproduce

1. Define a branded type in your code:

type PostId = string & { readonly __brand: "PostId" };

2. Create a helper function that returns queryOptions where the queryKey includes a value using this branded type:

const getPostQueryOptions = (
  params: MaybeRefOrGetter<{ postId: PostId }>
) => {
  return queryOptions({
    queryKey: ["post", params],
    queryFn: () => fetcher(toValue(params).postId),
  });
};

3. Call useQuery() using the result of this helper:

useQuery(getPostQueryOptions({ postId }));

4. Observe the TypeScript error:
No overload matches this call.
Overload 1 of 3, '(options: DefinedInitialQueryOptions<Post, Error, Post, MaybeRefDeep<string | (() => { postId: PostId; }) | { postId: PostId; }>[]>, queryClient?: QueryClient | undefined): UseQueryDefinedReturnType<...>', gave the following error.... ts(2769)

Expected behavior

useQuery() should correctly accept a QueryOptions object whose queryKey contains a branded (nominal) type.

In other words:
Passing the result of queryOptions(...) or any helper function that returns a QueryOptions object should not trigger a TypeScript overload error, even if the queryKey includes branded values.

How often does this bug happen?

Every time

Screenshots or Videos
Image Image
Platform
  • OS [Windows]
  • Browser [Chrome]
Tanstack Query adapter

vue-query

TanStack Query version

v5.85.3

TypeScript version

v5.9.2

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked CodeSandbox and its src/Post.vue reproduction, then trace the TypeScript overloads used by queryOptions and useQuery in the Vue adapter. Confirm the fix by making the branded queryKey helper compile without TS2769 while preserving the working fetchQuery and inline useQuery cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.