diff --git a/.changeset/tidy-cougars-serve.md b/.changeset/tidy-cougars-serve.md new file mode 100644 index 00000000000..278d61fe8ec --- /dev/null +++ b/.changeset/tidy-cougars-serve.md @@ -0,0 +1,5 @@ +--- +'@tanstack/query-core': patch +--- + +fix(query-core): setQueryData updater no longer loses discriminated-union members when spreading a narrowed value diff --git a/packages/query-core/src/__tests__/queryClient.test-d.tsx b/packages/query-core/src/__tests__/queryClient.test-d.tsx index a02fbc009b1..e1f352a7863 100644 --- a/packages/query-core/src/__tests__/queryClient.test-d.tsx +++ b/packages/query-core/src/__tests__/queryClient.test-d.tsx @@ -157,6 +157,27 @@ describe('queryClient', () => { expectTypeOf(data).toEqualTypeOf() }) + it('should narrow a discriminated union when spreading the updater value', () => { + type ProbeData = + | { kind: 'a'; value: number; requiredA: number } + | { kind: 'b'; value: number; requiredB: number } + const key = ['probe'] as DataTag, ProbeData> + const queryClient = new QueryClient() + + // Regression test for #11795: this call must compile without an + // explicit annotation on `prev` + queryClient.setQueryData(key, (prev) => { + expectTypeOf(prev).toEqualTypeOf() + if (!prev || prev.kind !== 'a') return prev + expectTypeOf(prev).toEqualTypeOf<{ + kind: 'a' + value: number + requiredA: number + }>() + return { ...prev, value: prev.value + 1 } + }) + }) + it('should type the value if the key is tagged', () => { const key = ['key'] as DataTag, number> const queryClient = new QueryClient() diff --git a/packages/query-core/src/queryClient.ts b/packages/query-core/src/queryClient.ts index 52a7c30fa55..7d3ddc98a59 100644 --- a/packages/query-core/src/queryClient.ts +++ b/packages/query-core/src/queryClient.ts @@ -289,7 +289,7 @@ export class QueryClient { >( queryKey: TTaggedQueryKey, updater: Updater< - NoInfer | undefined, + TInferredQueryFnData | undefined, NoInfer | undefined >, options?: SetDataOptions,