T
TanStack•12mo ago
xenial-black

How to switch between two queries based on condition (type-safe)

I have two queries, foo and bar, which are used separately in some React Components. I have a component that needs to use either foo or bar depending on some dynamic condition. When the condition changes, the old value should be kept until the new data is loaded (e.g. switching from foo to bar should still show foo until bar is ready). The foo query returns { value: string } and the bar query returns { value: string; otherProp: string }. For a function that returns either foo or bar, TypeScript infers the return type as an object with only the common properties (value), not a union type. For the conditional query this results in UseQueryResult<Foo> which is pretty confusing (it's not just foo, it's either foo or bar). Therefore I need to explicitly define the return type of the query function to be Foo | Bar. This is not directly related to TanStack Query but makes it harder to find a type-safe solution. Is there a simple, clean and type-safe way to define the two queries once (using queryOptions()) and then use them for both, the separate queries and the conditional combined query? Something like this (just to demostrante the idea:
export const fooQuery = () => queryOptions({ ... });
export const barQuery = () => queryOptions({ ... });

export function useFooOrBarQuery(value: boolean) {
return useQuery({
...(value ? fooQuery() : barQuery()),
placeholderData: keepPreviousData,
});
}
export const fooQuery = () => queryOptions({ ... });
export const barQuery = () => queryOptions({ ... });

export function useFooOrBarQuery(value: boolean) {
return useQuery({
...(value ? fooQuery() : barQuery()),
placeholderData: keepPreviousData,
});
}
I tried different solutions but none of them really worked: https://tsplay.dev/weqrKw My current solution is to just define three separate queries. We use type-safe query keys and the query functions are separated from the query hook, so it's not a bad solution. I just wonder If I missed something and if there is a simpler solution.
TS Playground - An online editor for exploring TypeScript and JavaS...
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
2 Replies
sensitive-blue
sensitive-blue•12mo ago
hm, I think the useQueries one is probably the best, even though I'm not sure if placeholderData works there 🤔
xenial-black
xenial-blackOP•12mo ago
Oh you're right, just tested it and placeholderData doesn't work in this case 😕

Did you find this page helpful?