UNPKG

15 kBTypeScriptView Raw
1import type { AnyAction, ThunkDispatch } from '@reduxjs/toolkit';
2import type { RootState } from './core/apiState';
3import type { BaseQueryExtraOptions, BaseQueryFn, BaseQueryResult, BaseQueryArg, BaseQueryApi, QueryReturnValue, BaseQueryError, BaseQueryMeta } from './baseQueryTypes';
4import type { HasRequiredProps, MaybePromise, OmitFromUnion, CastAny } from './tsHelpers';
5import type { NEVER } from './fakeBaseQuery';
6declare const resultType: unique symbol;
7declare const baseQuery: unique symbol;
8interface EndpointDefinitionWithQuery<QueryArg, BaseQuery extends BaseQueryFn, ResultType> {
9 /**
10 * `query` can be a function that returns either a `string` or an `object` which is passed to your `baseQuery`. If you are using [fetchBaseQuery](./fetchBaseQuery), this can return either a `string` or an `object` of properties in `FetchArgs`. If you use your own custom [`baseQuery`](../../rtk-query/usage/customizing-queries), you can customize this behavior to your liking.
11 *
12 * @example
13 *
14 * ```ts
15 * // codeblock-meta title="query example"
16 *
17 * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
18 * interface Post {
19 * id: number
20 * name: string
21 * }
22 * type PostsResponse = Post[]
23 *
24 * const api = createApi({
25 * baseQuery: fetchBaseQuery({ baseUrl: '/' }),
26 * endpoints: (build) => ({
27 * getPosts: build.query<PostsResponse, void>({
28 * // highlight-start
29 * query: () => 'posts',
30 * // highlight-end
31 * })
32 * })
33 * })
34 * ```
35 */
36 query(arg: QueryArg): BaseQueryArg<BaseQuery>;
37 queryFn?: never;
38 /**
39 * A function to manipulate the data returned by a query or mutation.
40 */
41 transformResponse?(baseQueryReturnValue: BaseQueryResult<BaseQuery>, meta: BaseQueryMeta<BaseQuery>): ResultType | Promise<ResultType>;
42}
43interface EndpointDefinitionWithQueryFn<QueryArg, BaseQuery extends BaseQueryFn, ResultType> {
44 /**
45 * Can be used in place of `query` as an inline function that bypasses `baseQuery` completely for the endpoint.
46 *
47 * @example
48 * ```ts
49 * // codeblock-meta title="Basic queryFn example"
50 *
51 * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
52 * interface Post {
53 * id: number
54 * name: string
55 * }
56 * type PostsResponse = Post[]
57 *
58 * const api = createApi({
59 * baseQuery: fetchBaseQuery({ baseUrl: '/' }),
60 * endpoints: (build) => ({
61 * getPosts: build.query<PostsResponse, void>({
62 * query: () => 'posts',
63 * }),
64 * flipCoin: build.query<'heads' | 'tails', void>({
65 * // highlight-start
66 * queryFn(arg, queryApi, extraOptions, baseQuery) {
67 * const randomVal = Math.random()
68 * if (randomVal < 0.45) {
69 * return { data: 'heads' }
70 * }
71 * if (randomVal < 0.9) {
72 * return { data: 'tails' }
73 * }
74 * return { error: { status: 500, statusText: 'Internal Server Error', data: "Coin landed on it's edge!" } }
75 * }
76 * // highlight-end
77 * })
78 * })
79 * })
80 * ```
81 */
82 queryFn(arg: QueryArg, api: BaseQueryApi, extraOptions: BaseQueryExtraOptions<BaseQuery>, baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>;
83 query?: never;
84 transformResponse?: never;
85}
86export declare type BaseEndpointDefinition<QueryArg, BaseQuery extends BaseQueryFn, ResultType> = (([CastAny<BaseQueryResult<BaseQuery>, {}>] extends [NEVER] ? never : EndpointDefinitionWithQuery<QueryArg, BaseQuery, ResultType>) | EndpointDefinitionWithQueryFn<QueryArg, BaseQuery, ResultType>) & {
87 [resultType]?: ResultType;
88 [baseQuery]?: BaseQuery;
89} & HasRequiredProps<BaseQueryExtraOptions<BaseQuery>, {
90 extraOptions: BaseQueryExtraOptions<BaseQuery>;
91}, {
92 extraOptions?: BaseQueryExtraOptions<BaseQuery>;
93}>;
94export declare enum DefinitionType {
95 query = "query",
96 mutation = "mutation"
97}
98export declare type GetResultDescriptionFn<TagTypes extends string, ResultType, QueryArg, ErrorType> = (result: ResultType | undefined, error: ErrorType | undefined, arg: QueryArg) => ReadonlyArray<TagDescription<TagTypes>>;
99export declare type FullTagDescription<TagType> = {
100 type: TagType;
101 id?: number | string;
102};
103export declare type TagDescription<TagType> = TagType | FullTagDescription<TagType>;
104export declare type ResultDescription<TagTypes extends string, ResultType, QueryArg, ErrorType> = ReadonlyArray<TagDescription<TagTypes>> | GetResultDescriptionFn<TagTypes, ResultType, QueryArg, ErrorType>;
105/** @deprecated please use `onQueryStarted` instead */
106export interface QueryApi<ReducerPath extends string, Context extends {}> {
107 /** @deprecated please use `onQueryStarted` instead */
108 dispatch: ThunkDispatch<any, any, AnyAction>;
109 /** @deprecated please use `onQueryStarted` instead */
110 getState(): RootState<any, any, ReducerPath>;
111 /** @deprecated please use `onQueryStarted` instead */
112 extra: unknown;
113 /** @deprecated please use `onQueryStarted` instead */
114 requestId: string;
115 /** @deprecated please use `onQueryStarted` instead */
116 context: Context;
117}
118export interface QueryExtraOptions<TagTypes extends string, ResultType, QueryArg, BaseQuery extends BaseQueryFn, ReducerPath extends string = string> {
119 type: DefinitionType.query;
120 /**
121 * Used by `query` endpoints. Determines which 'tag' is attached to the cached data returned by the query.
122 * Expects an array of tag type strings, an array of objects of tag types with ids, or a function that returns such an array.
123 * 1. `['Post']` - equivalent to `2`
124 * 2. `[{ type: 'Post' }]` - equivalent to `1`
125 * 3. `[{ type: 'Post', id: 1 }]`
126 * 4. `(result, error, arg) => ['Post']` - equivalent to `5`
127 * 5. `(result, error, arg) => [{ type: 'Post' }]` - equivalent to `4`
128 * 6. `(result, error, arg) => [{ type: 'Post', id: 1 }]`
129 *
130 * @example
131 *
132 * ```ts
133 * // codeblock-meta title="providesTags example"
134 *
135 * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
136 * interface Post {
137 * id: number
138 * name: string
139 * }
140 * type PostsResponse = Post[]
141 *
142 * const api = createApi({
143 * baseQuery: fetchBaseQuery({ baseUrl: '/' }),
144 * tagTypes: ['Posts'],
145 * endpoints: (build) => ({
146 * getPosts: build.query<PostsResponse, void>({
147 * query: () => 'posts',
148 * // highlight-start
149 * providesTags: (result) =>
150 * result
151 * ? [
152 * ...result.map(({ id }) => ({ type: 'Posts' as const, id })),
153 * { type: 'Posts', id: 'LIST' },
154 * ]
155 * : [{ type: 'Posts', id: 'LIST' }],
156 * // highlight-end
157 * })
158 * })
159 * })
160 * ```
161 */
162 providesTags?: ResultDescription<TagTypes, ResultType, QueryArg, BaseQueryError<BaseQuery>>;
163 /**
164 * Not to be used. A query should not invalidate tags in the cache.
165 */
166 invalidatesTags?: never;
167}
168export declare type QueryDefinition<QueryArg, BaseQuery extends BaseQueryFn, TagTypes extends string, ResultType, ReducerPath extends string = string> = BaseEndpointDefinition<QueryArg, BaseQuery, ResultType> & QueryExtraOptions<TagTypes, ResultType, QueryArg, BaseQuery, ReducerPath>;
169export interface MutationExtraOptions<TagTypes extends string, ResultType, QueryArg, BaseQuery extends BaseQueryFn, ReducerPath extends string = string> {
170 type: DefinitionType.mutation;
171 /**
172 * Used by `mutation` endpoints. Determines which cached data should be either re-fetched or removed from the cache.
173 * Expects the same shapes as `providesTags`.
174 *
175 * @example
176 *
177 * ```ts
178 * // codeblock-meta title="invalidatesTags example"
179 * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
180 * interface Post {
181 * id: number
182 * name: string
183 * }
184 * type PostsResponse = Post[]
185 *
186 * const api = createApi({
187 * baseQuery: fetchBaseQuery({ baseUrl: '/' }),
188 * tagTypes: ['Posts'],
189 * endpoints: (build) => ({
190 * getPosts: build.query<PostsResponse, void>({
191 * query: () => 'posts',
192 * providesTags: (result) =>
193 * result
194 * ? [
195 * ...result.map(({ id }) => ({ type: 'Posts' as const, id })),
196 * { type: 'Posts', id: 'LIST' },
197 * ]
198 * : [{ type: 'Posts', id: 'LIST' }],
199 * }),
200 * addPost: build.mutation<Post, Partial<Post>>({
201 * query(body) {
202 * return {
203 * url: `posts`,
204 * method: 'POST',
205 * body,
206 * }
207 * },
208 * // highlight-start
209 * invalidatesTags: [{ type: 'Posts', id: 'LIST' }],
210 * // highlight-end
211 * }),
212 * })
213 * })
214 * ```
215 */
216 invalidatesTags?: ResultDescription<TagTypes, ResultType, QueryArg, BaseQueryError<BaseQuery>>;
217 /**
218 * Not to be used. A mutation should not provide tags to the cache.
219 */
220 providesTags?: never;
221}
222export declare type MutationDefinition<QueryArg, BaseQuery extends BaseQueryFn, TagTypes extends string, ResultType, ReducerPath extends string = string> = BaseEndpointDefinition<QueryArg, BaseQuery, ResultType> & MutationExtraOptions<TagTypes, ResultType, QueryArg, BaseQuery, ReducerPath>;
223export declare type EndpointDefinition<QueryArg, BaseQuery extends BaseQueryFn, TagTypes extends string, ResultType, ReducerPath extends string = string> = QueryDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath> | MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>;
224export declare type EndpointDefinitions = Record<string, EndpointDefinition<any, any, any, any>>;
225export declare function isQueryDefinition(e: EndpointDefinition<any, any, any, any>): e is QueryDefinition<any, any, any, any>;
226export declare function isMutationDefinition(e: EndpointDefinition<any, any, any, any>): e is MutationDefinition<any, any, any, any>;
227export declare type EndpointBuilder<BaseQuery extends BaseQueryFn, TagTypes extends string, ReducerPath extends string> = {
228 /**
229 * An endpoint definition that retrieves data, and may provide tags to the cache.
230 *
231 * @example
232 * ```js
233 * // codeblock-meta title="Example of all query endpoint options"
234 * const api = createApi({
235 * baseQuery,
236 * endpoints: (build) => ({
237 * getPost: build.query({
238 * query: (id) => ({ url: `post/${id}` }),
239 * // Pick out data and prevent nested properties in a hook or selector
240 * transformResponse: (response) => response.data,
241 * // `result` is the server response
242 * providesTags: (result, error, id) => [{ type: 'Post', id }],
243 * // trigger side effects or optimistic updates
244 * onQueryStarted(id, { dispatch, getState, extra, requestId, queryFulfilled, getCacheEntry, updateCachedData }) {},
245 * // handle subscriptions etc
246 * onCacheEntryAdded(id, { dispatch, getState, extra, requestId, cacheEntryRemoved, cacheDataLoaded, getCacheEntry, updateCachedData }) {},
247 * }),
248 * }),
249 *});
250 *```
251 */
252 query<ResultType, QueryArg>(definition: OmitFromUnion<QueryDefinition<QueryArg, BaseQuery, TagTypes, ResultType>, 'type'>): QueryDefinition<QueryArg, BaseQuery, TagTypes, ResultType>;
253 /**
254 * An endpoint definition that alters data on the server or will possibly invalidate the cache.
255 *
256 * @example
257 * ```js
258 * // codeblock-meta title="Example of all mutation endpoint options"
259 * const api = createApi({
260 * baseQuery,
261 * endpoints: (build) => ({
262 * updatePost: build.mutation({
263 * query: ({ id, ...patch }) => ({ url: `post/${id}`, method: 'PATCH', body: patch }),
264 * // Pick out data and prevent nested properties in a hook or selector
265 * transformResponse: (response) => response.data,
266 * // `result` is the server response
267 * invalidatesTags: (result, error, id) => [{ type: 'Post', id }],
268 * // trigger side effects or optimistic updates
269 * onQueryStarted(id, { dispatch, getState, extra, requestId, queryFulfilled, getCacheEntry }) {},
270 * // handle subscriptions etc
271 * onCacheEntryAdded(id, { dispatch, getState, extra, requestId, cacheEntryRemoved, cacheDataLoaded, getCacheEntry }) {},
272 * }),
273 * }),
274 * });
275 * ```
276 */
277 mutation<ResultType, QueryArg>(definition: OmitFromUnion<MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>, 'type'>): MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>;
278};
279export declare type AssertTagTypes = <T extends FullTagDescription<string>>(t: T) => T;
280export declare function calculateProvidedBy<ResultType, QueryArg, ErrorType>(description: ResultDescription<string, ResultType, QueryArg, ErrorType> | undefined, result: ResultType | undefined, error: ErrorType | undefined, queryArg: QueryArg, assertTagTypes: AssertTagTypes): readonly FullTagDescription<string>[];
281export declare type QueryArgFrom<D extends BaseEndpointDefinition<any, any, any>> = D extends BaseEndpointDefinition<infer QA, any, any> ? QA : unknown;
282export declare type ResultTypeFrom<D extends BaseEndpointDefinition<any, any, any>> = D extends BaseEndpointDefinition<any, any, infer RT> ? RT : unknown;
283export declare type ReducerPathFrom<D extends EndpointDefinition<any, any, any, any>> = D extends EndpointDefinition<any, any, any, infer RP> ? RP : unknown;
284export declare type TagTypesFrom<D extends EndpointDefinition<any, any, any, any>> = D extends EndpointDefinition<any, any, infer RP, any> ? RP : unknown;
285export declare type ReplaceTagTypes<Definitions extends EndpointDefinitions, NewTagTypes extends string> = {
286 [K in keyof Definitions]: Definitions[K] extends QueryDefinition<infer QueryArg, infer BaseQuery, any, infer ResultType, infer ReducerPath> ? QueryDefinition<QueryArg, BaseQuery, NewTagTypes, ResultType, ReducerPath> : Definitions[K] extends MutationDefinition<infer QueryArg, infer BaseQuery, any, infer ResultType, infer ReducerPath> ? MutationDefinition<QueryArg, BaseQuery, NewTagTypes, ResultType, ReducerPath> : never;
287};
288export {};