From b4ea0d6a217698d6f0aca87a526865d30b3a390a Mon Sep 17 00:00:00 2001 From: Neef Rehman Date: Fri, 10 Jan 2025 15:10:35 +0000 Subject: [PATCH 1/2] feat(types): support typing QueryKey and MutationKey via Register --- docs/framework/react/typescript.md | 22 ++++++++++++++++++++++ packages/query-core/src/types.ts | 18 ++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/docs/framework/react/typescript.md b/docs/framework/react/typescript.md index cc2249dae02..990f9eb8a36 100644 --- a/docs/framework/react/typescript.md +++ b/docs/framework/react/typescript.md @@ -172,6 +172,28 @@ declare module '@tanstack/react-query' { ``` [//]: # 'TypingMeta' +[//]: # 'TypingQueryAndMutationKeys' + +## Typing query and mutation keys + +### Registering the query and mutation key types + +Also similarly to registering a [global error type](#registering-a-global-error), you can also register a global `QueryKey` and `MutationKey` type. This allows you to provide more structure to your keys, that matches your application's hierarchy, and have them be typed across all of the library's surface area. Note that the registered type must extend the `Array` type, so that your keys remain an array. + +```ts +import '@tanstack/react-query' + +type QueryKey = ["dashboard" | "marketing", ...ReadonlyArray] + +declare module '@tanstack/react-query' { + interface Register { + queryKey: QueryKey + mutationKey: QueryKey + } +} +``` + +[//]: # 'TypingQueryAndMutationKeys' [//]: # 'TypingQueryOptions' ## Typing Query Options diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index ce139b04d9a..3d203bdec59 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -32,6 +32,8 @@ export interface Register { // defaultError: Error // queryMeta: Record // mutationMeta: Record + // queryKey: ReadonlyArray + // mutationKey: ReadonlyArray } export type DefaultError = Register extends { @@ -40,7 +42,13 @@ export type DefaultError = Register extends { ? TError : Error -export type QueryKey = ReadonlyArray +export type QueryKey = Register extends { + queryKey: infer TQueryKey; +} + ? TQueryKey extends Array + ? TQueryKey + : ReadonlyArray + : ReadonlyArray; export const dataTagSymbol = Symbol('dataTagSymbol') export type dataTagSymbol = typeof dataTagSymbol @@ -996,7 +1004,13 @@ export type InfiniteQueryObserverResult< | InfiniteQueryObserverLoadingResult | InfiniteQueryObserverPendingResult -export type MutationKey = ReadonlyArray +export type MutationKey = Register extends { + mutationKey: infer TMutationKey; +} +? TMutationKey extends Array + ? TMutationKey + : ReadonlyArray +: ReadonlyArray; export type MutationStatus = 'idle' | 'pending' | 'success' | 'error' From 2b07bbeba8230b0e4bae6d9154d5402691ff8725 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:15:28 +0000 Subject: [PATCH 2/2] ci: apply automated fixes --- docs/framework/react/typescript.md | 2 +- packages/query-core/src/types.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/framework/react/typescript.md b/docs/framework/react/typescript.md index 990f9eb8a36..76d5423365f 100644 --- a/docs/framework/react/typescript.md +++ b/docs/framework/react/typescript.md @@ -183,7 +183,7 @@ Also similarly to registering a [global error type](#registering-a-global-error) ```ts import '@tanstack/react-query' -type QueryKey = ["dashboard" | "marketing", ...ReadonlyArray] +type QueryKey = ['dashboard' | 'marketing', ...ReadonlyArray] declare module '@tanstack/react-query' { interface Register { diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index 3d203bdec59..5014cfbf1fa 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -43,12 +43,12 @@ export type DefaultError = Register extends { : Error export type QueryKey = Register extends { - queryKey: infer TQueryKey; + queryKey: infer TQueryKey } ? TQueryKey extends Array ? TQueryKey : ReadonlyArray - : ReadonlyArray; + : ReadonlyArray export const dataTagSymbol = Symbol('dataTagSymbol') export type dataTagSymbol = typeof dataTagSymbol @@ -1005,12 +1005,12 @@ export type InfiniteQueryObserverResult< | InfiniteQueryObserverPendingResult export type MutationKey = Register extends { - mutationKey: infer TMutationKey; + mutationKey: infer TMutationKey } -? TMutationKey extends Array - ? TMutationKey + ? TMutationKey extends Array + ? TMutationKey + : ReadonlyArray : ReadonlyArray -: ReadonlyArray; export type MutationStatus = 'idle' | 'pending' | 'success' | 'error'