query: [v5 beta] Type inference for `useQuery` breaks when using `queryOptions` util and `select`
Describe the bug
When using the new queryOptions util from react-query v5, type inference seems to be a bit fragile. For example when spreading the resulting options object and adding a select statement to the query, the resulting data type is incorrect. More interestingly, the type seems to be inferred correctly if we also set the type refetchInterval option. I haven’t tested around exactly which other options trigger this behaviour, but I believe this data point should be helpful enough in fixing the issue.
import { queryOptions } from '@tanstack/react-query'
const options = queryOptions({
queryKey: ["key"],
queryFn: () => Promise.resolve(1),
});
// Type inference breaks, so TS complains about return type of select()
const query1 = useQuery({
...options,
select: (data) => data > 1
});
// Type inference works like it should, so query2.data has type boolean
const query2 = useQuery({
...options,
select: (data) => data > 1,
refetchInterval: 1,
});
// When inlining the query options, types are correct even without refetchInterval
const query3 = useQuery({
queryKey: ["key"],
queryFn: () => Promise.resolve(1),
select: (data) => data > 1,
});
Your minimal, reproducible example
https://codesandbox.io/p/sandbox/festive-platform-0krnf3?file=%2Fsrc%2FApp.tsx%3A21%2C28
Steps to reproduce
- Open the codesandbox
- See the ts errors in the editor
Expected behavior
The correct data type should be inferred from the return type of the select function in useQuery.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
v5.0.0-alpha.34
Tanstack Query adapter
react-query
TanStack Query version
v5.0.0-alpha.34
TypeScript version
v5.0.4
Additional context
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 15
No it doesn’t seem to work in the TS playground, but I think it’s broken in some way.
Try this barebones setup to reproduce:
Paste this in a typescript file called
tmp.tsand open project in vscodequery1will have an error on select,query2andquery3will have the correct types without errors.Yea I see that that’s the case at the moment, but it should be possible to write the types in a way that it works, as is evidence by my repro above where it works when refetchInterval is added. Something with the return type of queryOptions is making typescript trip. If a regular
useQuerycall can switch out the type when select is there, why shouldn’t one where we spread in queryOptions?If you don’t know how to solve this, then I guess there’s not much more to do. But please don’t dismiss it as not reproducible or impossible to fix 🙏 It really is reproducible if you try my example above.
Thank you for the patience!
you’re absolutely right. I thought that the options can’t be narrowed anymore once it’s set to
UndefinedInitialDataOptions, but seems like they can. Using the right type works, so that’s not an issue. Then the question is really: why doesn’t the same work for select 🤔