import type { AnyAction, ThunkDispatch } from '@reduxjs/toolkit';
import type { RootState } from './core/apiState';
import type { BaseQueryExtraOptions, BaseQueryFn, BaseQueryResult, BaseQueryArg, BaseQueryApi, QueryReturnValue, BaseQueryError, BaseQueryMeta } from './baseQueryTypes';
import type { HasRequiredProps, MaybePromise, OmitFromUnion, CastAny } from './tsHelpers';
import type { NEVER } from './fakeBaseQuery';
declare const resultType: unique symbol;
declare const baseQuery: unique symbol;
interface EndpointDefinitionWithQuery<QueryArg, BaseQuery extends BaseQueryFn, ResultType> {
    /**
     * `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.
     *
     * @example
     *
     * ```ts
     * // codeblock-meta title="query example"
     *
     * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
     * interface Post {
     *   id: number
     *   name: string
     * }
     * type PostsResponse = Post[]
     *
     * const api = createApi({
     *   baseQuery: fetchBaseQuery({ baseUrl: '/' }),
     *   endpoints: (build) => ({
     *     getPosts: build.query<PostsResponse, void>({
     *       // highlight-start
     *       query: () => 'posts',
     *       // highlight-end
     *     })
     *   })
     * })
     * ```
     */
    query(arg: QueryArg): BaseQueryArg<BaseQuery>;
    queryFn?: never;
    /**
     * A function to manipulate the data returned by a query or mutation.
     */
    transformResponse?(baseQueryReturnValue: BaseQueryResult<BaseQuery>, meta: BaseQueryMeta<BaseQuery>, arg: QueryArg): ResultType | Promise<ResultType>;
    /**
     * Defaults to `true`.
     *
     * Most apps should leave this setting on. The only time it can be a performance issue
     * is if an API returns extremely large amounts of data (e.g. 10,000 rows per request) and
     * you're unable to paginate it.
     *
     * For details of how this works, please see the below. When it is set to `false`,
     * every request will cause subscribed components to rerender, even when the data has not changed.
     *
     * @see https://redux-toolkit.js.org/api/other-exports#copywithstructuralsharing
     */
    structuralSharing?: boolean;
}
interface EndpointDefinitionWithQueryFn<QueryArg, BaseQuery extends BaseQueryFn, ResultType> {
    /**
     * Can be used in place of `query` as an inline function that bypasses `baseQuery` completely for the endpoint.
     *
     * @example
     * ```ts
     * // codeblock-meta title="Basic queryFn example"
     *
     * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
     * interface Post {
     *   id: number
     *   name: string
     * }
     * type PostsResponse = Post[]
     *
     * const api = createApi({
     *   baseQuery: fetchBaseQuery({ baseUrl: '/' }),
     *   endpoints: (build) => ({
     *     getPosts: build.query<PostsResponse, void>({
     *       query: () => 'posts',
     *     }),
     *     flipCoin: build.query<'heads' | 'tails', void>({
     *       // highlight-start
     *       queryFn(arg, queryApi, extraOptions, baseQuery) {
     *         const randomVal = Math.random()
     *         if (randomVal < 0.45) {
     *           return { data: 'heads' }
     *         }
     *         if (randomVal < 0.9) {
     *           return { data: 'tails' }
     *         }
     *         return { error: { status: 500, statusText: 'Internal Server Error', data: "Coin landed on it's edge!" } }
     *       }
     *       // highlight-end
     *     })
     *   })
     * })
     * ```
     */
    queryFn(arg: QueryArg, api: BaseQueryApi, extraOptions: BaseQueryExtraOptions<BaseQuery>, baseQuery: (arg: Parameters<BaseQuery>[0]) => ReturnType<BaseQuery>): MaybePromise<QueryReturnValue<ResultType, BaseQueryError<BaseQuery>>>;
    query?: never;
    transformResponse?: never;
    /**
     * Defaults to `true`.
     *
     * Most apps should leave this setting on. The only time it can be a performance issue
     * is if an API returns extremely large amounts of data (e.g. 10,000 rows per request) and
     * you're unable to paginate it.
     *
     * For details of how this works, please see the below. When it is set to `false`,
     * every request will cause subscribed components to rerender, even when the data has not changed.
     *
     * @see https://redux-toolkit.js.org/api/other-exports#copywithstructuralsharing
     */
    structuralSharing?: boolean;
}
export declare type BaseEndpointDefinition<QueryArg, BaseQuery extends BaseQueryFn, ResultType> = (([CastAny<BaseQueryResult<BaseQuery>, {}>] extends [NEVER] ? never : EndpointDefinitionWithQuery<QueryArg, BaseQuery, ResultType>) | EndpointDefinitionWithQueryFn<QueryArg, BaseQuery, ResultType>) & {
    [resultType]?: ResultType;
    [baseQuery]?: BaseQuery;
} & HasRequiredProps<BaseQueryExtraOptions<BaseQuery>, {
    extraOptions: BaseQueryExtraOptions<BaseQuery>;
}, {
    extraOptions?: BaseQueryExtraOptions<BaseQuery>;
}>;
export declare enum DefinitionType {
    query = "query",
    mutation = "mutation"
}
export declare type GetResultDescriptionFn<TagTypes extends string, ResultType, QueryArg, ErrorType, MetaType> = (result: ResultType | undefined, error: ErrorType | undefined, arg: QueryArg, meta: MetaType) => ReadonlyArray<TagDescription<TagTypes>>;
export declare type FullTagDescription<TagType> = {
    type: TagType;
    id?: number | string;
};
export declare type TagDescription<TagType> = TagType | FullTagDescription<TagType>;
export declare type ResultDescription<TagTypes extends string, ResultType, QueryArg, ErrorType, MetaType> = ReadonlyArray<TagDescription<TagTypes>> | GetResultDescriptionFn<TagTypes, ResultType, QueryArg, ErrorType, MetaType>;
/** @deprecated please use `onQueryStarted` instead */
export interface QueryApi<ReducerPath extends string, Context extends {}> {
    /** @deprecated please use `onQueryStarted` instead */
    dispatch: ThunkDispatch<any, any, AnyAction>;
    /** @deprecated please use `onQueryStarted` instead */
    getState(): RootState<any, any, ReducerPath>;
    /** @deprecated please use `onQueryStarted` instead */
    extra: unknown;
    /** @deprecated please use `onQueryStarted` instead */
    requestId: string;
    /** @deprecated please use `onQueryStarted` instead */
    context: Context;
}
export interface QueryExtraOptions<TagTypes extends string, ResultType, QueryArg, BaseQuery extends BaseQueryFn, ReducerPath extends string = string> {
    type: DefinitionType.query;
    /**
     * Used by `query` endpoints. Determines which 'tag' is attached to the cached data returned by the query.
     * Expects an array of tag type strings, an array of objects of tag types with ids, or a function that returns such an array.
     * 1.  `['Post']` - equivalent to `2`
     * 2.  `[{ type: 'Post' }]` - equivalent to `1`
     * 3.  `[{ type: 'Post', id: 1 }]`
     * 4.  `(result, error, arg) => ['Post']` - equivalent to `5`
     * 5.  `(result, error, arg) => [{ type: 'Post' }]` - equivalent to `4`
     * 6.  `(result, error, arg) => [{ type: 'Post', id: 1 }]`
     *
     * @example
     *
     * ```ts
     * // codeblock-meta title="providesTags example"
     *
     * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
     * interface Post {
     *   id: number
     *   name: string
     * }
     * type PostsResponse = Post[]
     *
     * const api = createApi({
     *   baseQuery: fetchBaseQuery({ baseUrl: '/' }),
     *   tagTypes: ['Posts'],
     *   endpoints: (build) => ({
     *     getPosts: build.query<PostsResponse, void>({
     *       query: () => 'posts',
     *       // highlight-start
     *       providesTags: (result) =>
     *         result
     *           ? [
     *               ...result.map(({ id }) => ({ type: 'Posts' as const, id })),
     *               { type: 'Posts', id: 'LIST' },
     *             ]
     *           : [{ type: 'Posts', id: 'LIST' }],
     *       // highlight-end
     *     })
     *   })
     * })
     * ```
     */
    providesTags?: ResultDescription<TagTypes, ResultType, QueryArg, BaseQueryError<BaseQuery>, BaseQueryMeta<BaseQuery>>;
    /**
     * Not to be used. A query should not invalidate tags in the cache.
     */
    invalidatesTags?: never;
}
export 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>;
export interface MutationExtraOptions<TagTypes extends string, ResultType, QueryArg, BaseQuery extends BaseQueryFn, ReducerPath extends string = string> {
    type: DefinitionType.mutation;
    /**
     * Used by `mutation` endpoints. Determines which cached data should be either re-fetched or removed from the cache.
     * Expects the same shapes as `providesTags`.
     *
     * @example
     *
     * ```ts
     * // codeblock-meta title="invalidatesTags example"
     * import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
     * interface Post {
     *   id: number
     *   name: string
     * }
     * type PostsResponse = Post[]
     *
     * const api = createApi({
     *   baseQuery: fetchBaseQuery({ baseUrl: '/' }),
     *   tagTypes: ['Posts'],
     *   endpoints: (build) => ({
     *     getPosts: build.query<PostsResponse, void>({
     *       query: () => 'posts',
     *       providesTags: (result) =>
     *         result
     *           ? [
     *               ...result.map(({ id }) => ({ type: 'Posts' as const, id })),
     *               { type: 'Posts', id: 'LIST' },
     *             ]
     *           : [{ type: 'Posts', id: 'LIST' }],
     *     }),
     *     addPost: build.mutation<Post, Partial<Post>>({
     *       query(body) {
     *         return {
     *           url: `posts`,
     *           method: 'POST',
     *           body,
     *         }
     *       },
     *       // highlight-start
     *       invalidatesTags: [{ type: 'Posts', id: 'LIST' }],
     *       // highlight-end
     *     }),
     *   })
     * })
     * ```
     */
    invalidatesTags?: ResultDescription<TagTypes, ResultType, QueryArg, BaseQueryError<BaseQuery>, BaseQueryMeta<BaseQuery>>;
    /**
     * Not to be used. A mutation should not provide tags to the cache.
     */
    providesTags?: never;
}
export 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>;
export 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>;
export declare type EndpointDefinitions = Record<string, EndpointDefinition<any, any, any, any>>;
export declare function isQueryDefinition(e: EndpointDefinition<any, any, any, any>): e is QueryDefinition<any, any, any, any>;
export declare function isMutationDefinition(e: EndpointDefinition<any, any, any, any>): e is MutationDefinition<any, any, any, any>;
export declare type EndpointBuilder<BaseQuery extends BaseQueryFn, TagTypes extends string, ReducerPath extends string> = {
    /**
     * An endpoint definition that retrieves data, and may provide tags to the cache.
     *
     * @example
     * ```js
     * // codeblock-meta title="Example of all query endpoint options"
     * const api = createApi({
     *  baseQuery,
     *  endpoints: (build) => ({
     *    getPost: build.query({
     *      query: (id) => ({ url: `post/${id}` }),
     *      // Pick out data and prevent nested properties in a hook or selector
     *      transformResponse: (response) => response.data,
     *      // `result` is the server response
     *      providesTags: (result, error, id) => [{ type: 'Post', id }],
     *      // trigger side effects or optimistic updates
     *      onQueryStarted(id, { dispatch, getState, extra, requestId, queryFulfilled, getCacheEntry, updateCachedData }) {},
     *      // handle subscriptions etc
     *      onCacheEntryAdded(id, { dispatch, getState, extra, requestId, cacheEntryRemoved, cacheDataLoaded, getCacheEntry, updateCachedData }) {},
     *    }),
     *  }),
     *});
     *```
     */
    query<ResultType, QueryArg>(definition: OmitFromUnion<QueryDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>, 'type'>): QueryDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>;
    /**
     * An endpoint definition that alters data on the server or will possibly invalidate the cache.
     *
     * @example
     * ```js
     * // codeblock-meta title="Example of all mutation endpoint options"
     * const api = createApi({
     *   baseQuery,
     *   endpoints: (build) => ({
     *     updatePost: build.mutation({
     *       query: ({ id, ...patch }) => ({ url: `post/${id}`, method: 'PATCH', body: patch }),
     *       // Pick out data and prevent nested properties in a hook or selector
     *       transformResponse: (response) => response.data,
     *       // `result` is the server response
     *       invalidatesTags: (result, error, id) => [{ type: 'Post', id }],
     *      // trigger side effects or optimistic updates
     *      onQueryStarted(id, { dispatch, getState, extra, requestId, queryFulfilled, getCacheEntry }) {},
     *      // handle subscriptions etc
     *      onCacheEntryAdded(id, { dispatch, getState, extra, requestId, cacheEntryRemoved, cacheDataLoaded, getCacheEntry }) {},
     *     }),
     *   }),
     * });
     * ```
     */
    mutation<ResultType, QueryArg>(definition: OmitFromUnion<MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>, 'type'>): MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>;
};
export declare type AssertTagTypes = <T extends FullTagDescription<string>>(t: T) => T;
export declare function calculateProvidedBy<ResultType, QueryArg, ErrorType, MetaType>(description: ResultDescription<string, ResultType, QueryArg, ErrorType, MetaType> | undefined, result: ResultType | undefined, error: ErrorType | undefined, queryArg: QueryArg, meta: MetaType | undefined, assertTagTypes: AssertTagTypes): readonly FullTagDescription<string>[];
export declare function expandTagDescription(description: TagDescription<string>): FullTagDescription<string>;
export declare type QueryArgFrom<D extends BaseEndpointDefinition<any, any, any>> = D extends BaseEndpointDefinition<infer QA, any, any> ? QA : unknown;
export declare type ResultTypeFrom<D extends BaseEndpointDefinition<any, any, any>> = D extends BaseEndpointDefinition<any, any, infer RT> ? RT : unknown;
export declare type ReducerPathFrom<D extends EndpointDefinition<any, any, any, any, any>> = D extends EndpointDefinition<any, any, any, any, infer RP> ? RP : unknown;
export declare type TagTypesFrom<D extends EndpointDefinition<any, any, any, any>> = D extends EndpointDefinition<any, any, infer RP, any> ? RP : unknown;
export declare type ReplaceTagTypes<Definitions extends EndpointDefinitions, NewTagTypes extends string> = {
    [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;
};
export {};
