Describe the bug
With @tanstack/react-query@5.104.0, setQueryData infers the correct data type from a queryOptions key, but narrowing and spreading that union inside the updater produces a false assignability error. Explicitly annotating the updater parameter as Data | undefined makes the same code compile.
Minimal reproduction
import { QueryClient, queryOptions } from '@tanstack/react-query';
type Data =
| { kind: 'a'; value: number; requiredA: number }
| { kind: 'b'; value: number; requiredB: number };
const query = queryOptions({
queryKey: ['probe'],
queryFn: async (): Promise<Data> => ({ kind: 'a', value: 1, requiredA: 1 }),
});
const client = new QueryClient();
client.setQueryData(query.queryKey, (prev) => {
if (!prev || prev.kind !== 'a') return prev;
return { ...prev, value: prev.value + 1 };
});
Run with TypeScript 5.8.3:
tsc --noEmit --strict --skipLibCheck --target es2023 --moduleResolution bundler --module esnext repro.ts
Actual behavior
TS2345: the callback return is inferred as NoInfer<Data> | { value: number; kind: 'a' | 'b' } | undefined. The spread loses the variant-specific required fields, so the returned object is rejected as Data.
Expected behavior
After the guard, spreading prev should preserve kind: 'a' and requiredA. The updater should compile without repeating the data type already encoded in the query key.
Workaround
Changing only (prev) to (prev: Data | undefined) compiles.
Versions and related context
@tanstack/react-query: 5.104.0
- TypeScript: 5.8.3
- Reproduces during typechecking; no browser or network calls needed.
Related: #11018 and #11245 address the useQuery return type. This report concerns the remaining NoInfer interaction in QueryClient.setQueryData updater parameters. The inferred key type itself is correct; the failure occurs during union narrowing/spread.
Describe the bug
With
@tanstack/react-query@5.104.0,setQueryDatainfers the correct data type from aqueryOptionskey, but narrowing and spreading that union inside the updater produces a false assignability error. Explicitly annotating the updater parameter asData | undefinedmakes the same code compile.Minimal reproduction
Run with TypeScript 5.8.3:
Actual behavior
TS2345: the callback return is inferred as
NoInfer<Data> | { value: number; kind: 'a' | 'b' } | undefined. The spread loses the variant-specific required fields, so the returned object is rejected asData.Expected behavior
After the guard, spreading
prevshould preservekind: 'a'andrequiredA. The updater should compile without repeating the data type already encoded in the query key.Workaround
Changing only
(prev)to(prev: Data | undefined)compiles.Versions and related context
@tanstack/react-query: 5.104.0Related: #11018 and #11245 address the
useQueryreturn type. This report concerns the remainingNoInferinteraction inQueryClient.setQueryDataupdater parameters. The inferred key type itself is correct; the failure occurs during union narrowing/spread.