Branded queryKey in queryOptions causes TS error (TS2769) in useQuery
Nobody has claimed this yet.
- 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
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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