From 5ce06d17377a5f34d14db1230ce0c76bb0e9ccf9 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Wed, 23 Oct 2024 12:51:23 +0100 Subject: [PATCH] Add `serializeQueryArgs` type support --- .../toolkit/src/query/endpointDefinitions.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/packages/toolkit/src/query/endpointDefinitions.ts b/packages/toolkit/src/query/endpointDefinitions.ts index 7add4311ce..0e206b323b 100644 --- a/packages/toolkit/src/query/endpointDefinitions.ts +++ b/packages/toolkit/src/query/endpointDefinitions.ts @@ -598,6 +598,67 @@ export interface InfiniteQueryExtraOptions< infiniteQueryOptions: InfiniteQueryConfigOptions + /** + * Can be provided to return a custom cache key value based on the query arguments. + * + * This is primarily intended for cases where a non-serializable value is passed as part of the query arg object and should be excluded from the cache key. It may also be used for cases where an endpoint should only have a single cache entry, such as an infinite loading / pagination implementation. + * + * Unlike the `createApi` version which can _only_ return a string, this per-endpoint option can also return an an object, number, or boolean. If it returns a string, that value will be used as the cache key directly. If it returns an object / number / boolean, that value will be passed to the built-in `defaultSerializeQueryArgs`. This simplifies the use case of stripping out args you don't want included in the cache key. + * + * + * @example + * + * ```ts + * // codeblock-meta title="serializeQueryArgs : exclude value" + * + * import { createApi, fetchBaseQuery, defaultSerializeQueryArgs } from '@reduxjs/toolkit/query/react' + * interface Post { + * id: number + * name: string + * } + * + * interface MyApiClient { + * fetchPost: (id: string) => Promise + * } + * + * createApi({ + * baseQuery: fetchBaseQuery({ baseUrl: '/' }), + * endpoints: (build) => ({ + * // Example: an endpoint with an API client passed in as an argument, + * // but only the item ID should be used as the cache key + * getPost: build.query({ + * queryFn: async ({ id, client }) => { + * const post = await client.fetchPost(id) + * return { data: post } + * }, + * // highlight-start + * serializeQueryArgs: ({ queryArgs, endpointDefinition, endpointName }) => { + * const { id } = queryArgs + * // This can return a string, an object, a number, or a boolean. + * // If it returns an object, number or boolean, that value + * // will be serialized automatically via `defaultSerializeQueryArgs` + * return { id } // omit `client` from the cache key + * + * // Alternately, you can use `defaultSerializeQueryArgs` yourself: + * // return defaultSerializeQueryArgs({ + * // endpointName, + * // queryArgs: { id }, + * // endpointDefinition + * // }) + * // Or create and return a string yourself: + * // return `getPost(${id})` + * }, + * // highlight-end + * }), + * }), + *}) + * ``` + */ + serializeQueryArgs?: SerializeQueryArgs< + QueryArg, + string | number | boolean | Record + > + /** * All of these are `undefined` at runtime, purely to be used in TypeScript declarations! */