From 6c0c7978db89855cf1203e0102c354a9ae741078 Mon Sep 17 00:00:00 2001 From: TkDodo Date: Fri, 14 Nov 2025 09:06:43 +0100 Subject: [PATCH 1/4] fix(types): do not drop readonly for partial QueryFilter matching --- packages/query-core/src/__tests__/utils.test-d.tsx | 14 +++++++++++++- packages/query-core/src/utils.ts | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/query-core/src/__tests__/utils.test-d.tsx b/packages/query-core/src/__tests__/utils.test-d.tsx index 3aacc61b81..8c87636e9a 100644 --- a/packages/query-core/src/__tests__/utils.test-d.tsx +++ b/packages/query-core/src/__tests__/utils.test-d.tsx @@ -50,7 +50,7 @@ describe('QueryFilters', () => { expectTypeOf(filters.queryKey).toEqualTypeOf< | undefined | readonly [] - | ['key'] + | readonly ['key'] | readonly [ 'key', { @@ -61,6 +61,18 @@ describe('QueryFilters', () => { >() }) + it('should work with readonly union types', () => { + const filters: QueryFilters< + readonly ['key'] | readonly ['key', 'something'] + > = { + queryKey: ['key'], + } + + expectTypeOf(filters.queryKey).toEqualTypeOf< + undefined | readonly [] | readonly ['key'] | readonly ['key', 'something'] + >() + }) + it('should error on invalid query keys', () => { assertType>({ // @ts-expect-error cannot pass invalid query key diff --git a/packages/query-core/src/utils.ts b/packages/query-core/src/utils.ts index 1be53edd2d..7f3baf25fc 100644 --- a/packages/query-core/src/utils.ts +++ b/packages/query-core/src/utils.ts @@ -20,7 +20,7 @@ type DropLast> = T extends readonly [ ...infer R, unknown, ] - ? R + ? readonly [...R] : never type TuplePrefixes> = T extends readonly [] From 604dbf25a9cc82aef2914d6423ed8ee840942cdf Mon Sep 17 00:00:00 2001 From: TkDodo Date: Sun, 16 Nov 2025 18:56:35 +0100 Subject: [PATCH 2/4] fix(types): allow QueryFilters union with different lengths --- packages/query-core/src/__tests__/utils.test-d.tsx | 13 +++++++++++++ packages/query-core/src/utils.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/query-core/src/__tests__/utils.test-d.tsx b/packages/query-core/src/__tests__/utils.test-d.tsx index 8c87636e9a..fd70e7cfb7 100644 --- a/packages/query-core/src/__tests__/utils.test-d.tsx +++ b/packages/query-core/src/__tests__/utils.test-d.tsx @@ -73,6 +73,19 @@ describe('QueryFilters', () => { >() }) + // we test that there are not type errors here + // eslint-disable-next-line vitest/expect-expect + it('should work with unions of different lengths', () => { + type Key = + | readonly ['foo'] + | readonly ['foo', 'bar'] + | readonly ['foo', 'bar', 'baz'] + + const queryKey: Key = ['foo', 'bar'] as any as Key + + new QueryClient().invalidateQueries({ queryKey }) + }) + it('should error on invalid query keys', () => { assertType>({ // @ts-expect-error cannot pass invalid query key diff --git a/packages/query-core/src/utils.ts b/packages/query-core/src/utils.ts index 7f3baf25fc..dadc6d7bc3 100644 --- a/packages/query-core/src/utils.ts +++ b/packages/query-core/src/utils.ts @@ -43,7 +43,7 @@ export interface QueryFilters { /** * Include queries matching this query key */ - queryKey?: TuplePrefixes + queryKey?: TQueryKey | TuplePrefixes /** * Include or exclude stale queries */ From 72584406db1c75413aa4e59c7785698e3d63f062 Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sun, 16 Nov 2025 18:57:21 +0100 Subject: [PATCH 3/4] Create orange-boxes-visit.md --- .changeset/orange-boxes-visit.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/orange-boxes-visit.md diff --git a/.changeset/orange-boxes-visit.md b/.changeset/orange-boxes-visit.md new file mode 100644 index 0000000000..ac6729f13c --- /dev/null +++ b/.changeset/orange-boxes-visit.md @@ -0,0 +1,5 @@ +--- +"@tanstack/query-core": patch +--- + +fix(types): do not drop readonly for partial QueryFilter matching From 601f14bc180b4950ad1fca7f334877e2eedbfafd Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Sun, 16 Nov 2025 19:17:46 +0100 Subject: [PATCH 4/4] Apply suggestion from @TkDodo --- .changeset/orange-boxes-visit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/orange-boxes-visit.md b/.changeset/orange-boxes-visit.md index ac6729f13c..da83a15050 100644 --- a/.changeset/orange-boxes-visit.md +++ b/.changeset/orange-boxes-visit.md @@ -2,4 +2,4 @@ "@tanstack/query-core": patch --- -fix(types): do not drop readonly for partial QueryFilter matching +fix(types): allow QueryFilters union with different lengths