mirror of
https://github.com/FlipsideCrypto/DefinitelyTyped.git
synced 2026-02-06 10:56:53 +00:00
[react-query] Update API to 1.10.0 (#43438)
* [react-query] Update API to 1.10.0 - breaking changes * Make use of extra variables * Fixing lint errors * Complete useInfiniteQuery * Add global config * Add queryCache * Allow keys and variables with infinite tails * Add discriminated unions for base and paginated queries * Discriminated union for mutation result * Require first key element to be a string subtype
This commit is contained in:
parent
21c3e41669
commit
2ea0ccd01f
474
types/react-query/index.d.ts
vendored
474
types/react-query/index.d.ts
vendored
@ -1,32 +1,171 @@
|
||||
// Type definitions for react-query 0.3
|
||||
// Type definitions for react-query 1.1
|
||||
// Project: https://github.com/tannerlinsley/react-query
|
||||
// Definitions by: Lukasz Fiszer <https://github.com/lukaszfiszer>
|
||||
// Jace Hensley <https://github.com/jacehensley>
|
||||
// Matteo Frana <https://github.com/matteofrana>
|
||||
// Igor Oleinikov <https://github.com/igorbek>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// Minimum TypeScript Version: 3.7
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import * as React from 'react';
|
||||
import * as _ from 'ts-toolbelt';
|
||||
|
||||
// overloaded useQuery function with pagination
|
||||
export function useQuery<TResult, TVariables extends object>(
|
||||
queryKey: QueryKey<TVariables>,
|
||||
queryFn: QueryFunction<TResult, TVariables>,
|
||||
options: QueryOptionsPaginated<TResult>
|
||||
): QueryResultPaginated<TResult, TVariables>;
|
||||
// overloaded useQuery function
|
||||
export function useQuery<TResult, TKey extends AnyQueryKey>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: QueryFunction<TResult, TKey>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): QueryResult<TResult>;
|
||||
|
||||
export function useQuery<TResult, TVariables extends object>(
|
||||
queryKey: QueryKey<TVariables>,
|
||||
queryFn: QueryFunction<TResult, TVariables>,
|
||||
options?: QueryOptions<TResult>
|
||||
): QueryResult<TResult, TVariables>;
|
||||
export function useQuery<TResult, TKey extends string>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: QueryFunction<TResult, [TKey]>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): QueryResult<TResult>;
|
||||
|
||||
export type QueryKey<TVariables> = string | [string, TVariables] | false | null | QueryKeyFunction<TVariables>;
|
||||
export type QueryKeyFunction<TVariables> = () => string | [string, TVariables] | false | null;
|
||||
export function useQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: QueryFunctionWithVariables<TResult, TKey, TVariables>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): QueryResult<TResult>;
|
||||
|
||||
export type QueryFunction<TResult, TVariables extends object> = (variables: TVariables) => Promise<TResult>;
|
||||
export function useQuery<TResult, TKey extends string, TVariables extends AnyVariables>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: QueryFunctionWithVariables<TResult, [TKey], TVariables>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): QueryResult<TResult>;
|
||||
|
||||
export interface QueryOptions<TResult> {
|
||||
export function useQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables = []>({
|
||||
queryKey,
|
||||
variables,
|
||||
queryFn,
|
||||
config,
|
||||
}: {
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined);
|
||||
variables?: TVariables;
|
||||
queryFn: QueryFunctionWithVariables<TResult, TKey, TVariables>;
|
||||
config?: QueryOptions<TResult>;
|
||||
}): QueryResult<TResult>;
|
||||
|
||||
// usePaginatedQuery
|
||||
export function usePaginatedQuery<TResult, TKey extends AnyQueryKey>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: QueryFunction<TResult, TKey>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): PaginatedQueryResult<TResult>;
|
||||
|
||||
export function usePaginatedQuery<TResult, TKey extends string>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: QueryFunction<TResult, [TKey]>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): PaginatedQueryResult<TResult>;
|
||||
|
||||
export function usePaginatedQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: QueryFunctionWithVariables<TResult, TKey, TVariables>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): PaginatedQueryResult<TResult>;
|
||||
|
||||
export function usePaginatedQuery<TResult, TKey extends string, TVariables extends AnyVariables>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: QueryFunctionWithVariables<TResult, [TKey], TVariables>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): PaginatedQueryResult<TResult>;
|
||||
|
||||
export function usePaginatedQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables = []>({
|
||||
queryKey,
|
||||
variables,
|
||||
queryFn,
|
||||
config,
|
||||
}: {
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined);
|
||||
variables?: TVariables;
|
||||
queryFn: QueryFunctionWithVariables<TResult, TKey, TVariables>;
|
||||
config?: QueryOptions<TResult>;
|
||||
}): PaginatedQueryResult<TResult>;
|
||||
|
||||
// useInfiniteQuery
|
||||
export function useInfiniteQuery<TResult, TKey extends AnyQueryKey, TMoreVariable>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: InfiniteQueryFunction<TResult, TKey, TMoreVariable>,
|
||||
config?: InfiniteQueryOptions<TResult, TMoreVariable>,
|
||||
): InfiniteQueryResult<TResult, TMoreVariable>;
|
||||
|
||||
export function useInfiniteQuery<TResult, TKey extends string, TMoreVariable>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: InfiniteQueryFunction<TResult, [TKey], TMoreVariable>,
|
||||
config?: InfiniteQueryOptions<TResult, TMoreVariable>,
|
||||
): InfiniteQueryResult<TResult, TMoreVariable>;
|
||||
|
||||
export function useInfiniteQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables, TMoreVariable>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: InfiniteQueryFunctionWithVariables<TResult, TKey, TVariables, TMoreVariable>,
|
||||
config?: InfiniteQueryOptions<TResult, TMoreVariable>,
|
||||
): InfiniteQueryResult<TResult, TMoreVariable>;
|
||||
|
||||
export function useInfiniteQuery<TResult, TKey extends string, TVariables extends AnyVariables, TMoreVariable>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: InfiniteQueryFunctionWithVariables<TResult, [TKey], TVariables, TMoreVariable>,
|
||||
config?: InfiniteQueryOptions<TResult, TMoreVariable>,
|
||||
): InfiniteQueryResult<TResult, TMoreVariable>;
|
||||
|
||||
export function useInfiniteQuery<
|
||||
TResult,
|
||||
TKey extends AnyQueryKey,
|
||||
TMoreVariable,
|
||||
TVariables extends AnyVariables = []
|
||||
>({
|
||||
queryKey,
|
||||
variables,
|
||||
queryFn,
|
||||
config,
|
||||
}: {
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined);
|
||||
variables?: TVariables;
|
||||
queryFn: InfiniteQueryFunctionWithVariables<TResult, TKey, TVariables, TMoreVariable>;
|
||||
config?: InfiniteQueryOptions<TResult, TMoreVariable>;
|
||||
}): InfiniteQueryResult<TResult, TMoreVariable>;
|
||||
|
||||
export type QueryKeyPart = string | object | boolean | number | null | readonly QueryKeyPart[] | null | undefined;
|
||||
export type AnyQueryKey = readonly [string, ...QueryKeyPart[]]; // this forces the key to be inferred as a tuple
|
||||
export type AnyVariables = readonly [] | readonly [any, ...any[]]; // this forces the variables to be inferred as a tuple
|
||||
|
||||
export type QueryFunction<TResult, TKey extends AnyQueryKey> = (...key: TKey) => Promise<TResult>;
|
||||
export type QueryFunctionWithVariables<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables> = (
|
||||
...key: _.List.Concat<TKey, TVariables>
|
||||
) => Promise<TResult>;
|
||||
|
||||
export type InfiniteQueryFunction<TResult, TKey extends AnyQueryKey, TMoreVariable> = (
|
||||
...keysAndMore: _.List.Append<TKey, TMoreVariable> | TKey
|
||||
) => Promise<TResult>;
|
||||
export type InfiniteQueryFunctionWithVariables<
|
||||
TResult,
|
||||
TKey extends AnyQueryKey,
|
||||
TVariables extends AnyVariables,
|
||||
TMoreVariable
|
||||
> = (
|
||||
...keysAndVariablesAndMore:
|
||||
| _.List.Append<_.List.Concat<TKey, TVariables>, TMoreVariable>
|
||||
| _.List.Concat<TKey, TVariables>
|
||||
) => Promise<TResult>;
|
||||
|
||||
export interface BaseQueryOptions {
|
||||
/**
|
||||
* Set this to `true` to disable automatic refetching when the query mounts or changes query keys.
|
||||
* To refetch the query, use the `refetch` method returned from the `useQuery` instance.
|
||||
*/
|
||||
manual?: boolean;
|
||||
/**
|
||||
* If `false`, failed queries will not retry by default.
|
||||
* If `true`, failed queries will retry infinitely.
|
||||
* If set to an integer number, e.g. 3, failed queries will retry until the failed query count meets that number.
|
||||
*/
|
||||
retry?: boolean | number;
|
||||
retryDelay?: (retryAttempt: number) => number;
|
||||
staleTime?: number;
|
||||
@ -34,109 +173,248 @@ export interface QueryOptions<TResult> {
|
||||
refetchInterval?: false | number;
|
||||
refetchIntervalInBackground?: boolean;
|
||||
refetchOnWindowFocus?: boolean;
|
||||
onError?: (err: any) => void;
|
||||
onSuccess?: (data: TResult) => void;
|
||||
refetchOnMount?: boolean;
|
||||
onError?: (err: unknown) => void;
|
||||
suspense?: boolean;
|
||||
}
|
||||
|
||||
export interface QueryOptions<TResult> extends BaseQueryOptions {
|
||||
onSuccess?: (data: TResult) => void;
|
||||
onSettled?: (data: TResult | undefined, error: unknown | null) => void;
|
||||
initialData?: TResult;
|
||||
}
|
||||
|
||||
export interface QueryOptionsPaginated<TResult> extends QueryOptions<TResult> {
|
||||
paginated: true;
|
||||
getCanFetchMore: (lastPage: TResult, allPages: TResult[]) => boolean;
|
||||
export interface InfiniteQueryOptions<TResult, TMoreVariable> extends QueryOptions<TResult> {
|
||||
getFetchMore: (lastPage: TResult, allPages: TResult[]) => TMoreVariable | false;
|
||||
}
|
||||
|
||||
export interface QueryResult<TResult, TVariables> {
|
||||
data: null | TResult;
|
||||
error: null | Error;
|
||||
isLoading: boolean;
|
||||
export interface QueryResultBase<TResult> {
|
||||
status: 'loading' | 'error' | 'success';
|
||||
error: null | unknown;
|
||||
isFetching: boolean;
|
||||
isCached: boolean;
|
||||
failureCount: number;
|
||||
refetch: (arg?: {variables?: TVariables, merge?: (...args: any[]) => any, disableThrow?: boolean}) => Promise<void>;
|
||||
refetch: ({ force, throwOnError }?: { force?: boolean; throwOnError?: boolean }) => Promise<TResult>;
|
||||
}
|
||||
|
||||
export interface QueryResultPaginated<TResult, TVariables> extends QueryResult<TResult[], TVariables> {
|
||||
export interface QueryLoadingResult<TResult> extends QueryResultBase<TResult> {
|
||||
status: 'loading';
|
||||
data: TResult | undefined; // even when error, data can have stale data
|
||||
error: unknown | null; // it still can be error
|
||||
}
|
||||
|
||||
export interface QueryErrorResult<TResult> extends QueryResultBase<TResult> {
|
||||
status: 'error';
|
||||
data: TResult | undefined; // even when error, data can have stale data
|
||||
error: unknown;
|
||||
}
|
||||
|
||||
export interface QuerySuccessResult<TResult> extends QueryResultBase<TResult> {
|
||||
status: 'success';
|
||||
data: TResult;
|
||||
error: null;
|
||||
}
|
||||
|
||||
export type QueryResult<TResult> =
|
||||
| QueryLoadingResult<TResult>
|
||||
| QueryErrorResult<TResult>
|
||||
| QuerySuccessResult<TResult>;
|
||||
|
||||
export interface PaginatedQueryLoadingResult<TResult> extends QueryResultBase<TResult> {
|
||||
status: 'loading';
|
||||
resolvedData: undefined | TResult; // even when error, data can have stale data
|
||||
latestData: undefined | TResult; // even when error, data can have stale data
|
||||
error: unknown | null; // it still can be error
|
||||
}
|
||||
|
||||
export interface PaginatedQueryErrorResult<TResult> extends QueryResultBase<TResult> {
|
||||
status: 'error';
|
||||
resolvedData: undefined | TResult; // even when error, data can have stale data
|
||||
latestData: undefined | TResult; // even when error, data can have stale data
|
||||
error: unknown;
|
||||
}
|
||||
|
||||
export interface PaginatedQuerySuccessResult<TResult> extends QueryResultBase<TResult> {
|
||||
status: 'success';
|
||||
resolvedData: TResult;
|
||||
latestData: TResult;
|
||||
error: null;
|
||||
}
|
||||
|
||||
export type PaginatedQueryResult<TResult> =
|
||||
| PaginatedQueryLoadingResult<TResult>
|
||||
| PaginatedQueryErrorResult<TResult>
|
||||
| PaginatedQuerySuccessResult<TResult>;
|
||||
|
||||
export interface InfiniteQueryResult<TResult, TMoreVariable> extends QueryResultBase<TResult[]> {
|
||||
data: TResult[];
|
||||
isFetchingMore: boolean;
|
||||
canFetchMore: boolean;
|
||||
fetchMore: (variables?: TVariables) => Promise<TResult>;
|
||||
fetchMore: (moreVariable?: TMoreVariable | false) => Promise<TResult[]> | undefined;
|
||||
}
|
||||
|
||||
export function prefetchQuery<TResult, TVariables extends object>(
|
||||
queryKey: QueryKey<TVariables>,
|
||||
queryFn: QueryFunction<TResult, TVariables>,
|
||||
options?: PrefetchQueryOptions<TResult>
|
||||
): Promise<TResult>;
|
||||
|
||||
export interface PrefetchQueryOptions<TResult> extends QueryOptions<TResult> {
|
||||
force?: boolean;
|
||||
}
|
||||
|
||||
export function useMutation<TResults, TVariables extends object>(
|
||||
export function useMutation<TResults, TVariables = undefined>(
|
||||
mutationFn: MutationFunction<TResults, TVariables>,
|
||||
mutationOptions?: MutationOptions
|
||||
mutationOptions?: MutationOptions<TResults, TVariables>,
|
||||
): [MutateFunction<TResults, TVariables>, MutationResult<TResults>];
|
||||
|
||||
export type MutationFunction<TResults, TVariables extends object> = (
|
||||
variables: TVariables,
|
||||
) => Promise<TResults>;
|
||||
export type MutationFunction<TResults, TVariables> = (variables: TVariables) => Promise<TResults>;
|
||||
|
||||
export interface MutationOptions {
|
||||
refetchQueries?: Array<string | [string, object]>;
|
||||
refetchQueriesOnFailure?: boolean;
|
||||
export interface MutateOptions<TResult, TVariables> {
|
||||
onSuccess?: (data: TResult, variables: TVariables) => Promise<void> | void;
|
||||
onError?: (error: unknown, variables: TVariables, snapshotValue: unknown) => Promise<void> | void;
|
||||
onSettled?: (
|
||||
data: undefined | TResult,
|
||||
error: unknown | null,
|
||||
variables: TVariables,
|
||||
snapshotValue?: unknown,
|
||||
) => Promise<void> | void;
|
||||
throwOnError?: boolean;
|
||||
}
|
||||
|
||||
export type MutateFunction<TResults, TVariables extends object> = (
|
||||
variables?: TVariables,
|
||||
options?: {
|
||||
updateQuery?: string | [string, object],
|
||||
waitForRefetchQueries?: boolean;
|
||||
}
|
||||
) => Promise<TResults>;
|
||||
export interface MutationOptions<TResult, TVariables> extends MutateOptions<TResult, TVariables> {
|
||||
onMutate?: (variables: TVariables) => Promise<unknown> | unknown;
|
||||
useErrorBoundary?: boolean;
|
||||
}
|
||||
|
||||
export interface MutationResult<TResults> {
|
||||
data: TResults | null;
|
||||
isLoading: boolean;
|
||||
error: null | Error;
|
||||
promise: Promise<TResults>;
|
||||
export type MutateFunction<TResult, TVariables> = undefined extends TVariables
|
||||
? (variables?: TVariables, options?: MutateOptions<TResult, TVariables>) => Promise<TResult>
|
||||
: (variables: TVariables, options?: MutateOptions<TResult, TVariables>) => Promise<TResult>;
|
||||
|
||||
export interface MutationResultBase<TResult> {
|
||||
status: 'idle' | 'loading' | 'error' | 'success';
|
||||
data: undefined | TResult;
|
||||
error: null | unknown;
|
||||
promise: Promise<TResult>;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
export function setQueryData(
|
||||
queryKey: string | [string, object],
|
||||
data: any,
|
||||
options?: {
|
||||
shouldRefetch?: boolean
|
||||
}
|
||||
): void | Promise<void>;
|
||||
|
||||
export function refetchQuery(
|
||||
queryKey: string | [string, object] | [string, false],
|
||||
force?: {
|
||||
force?: boolean
|
||||
}
|
||||
): Promise<void>;
|
||||
|
||||
export function refetchAllQueries(
|
||||
options?: {
|
||||
force?: boolean,
|
||||
includeInactive: boolean
|
||||
}
|
||||
): Promise<void>;
|
||||
|
||||
export function useIsFetching(): boolean;
|
||||
|
||||
export const ReactQueryConfigProvider: React.ComponentType<{
|
||||
config?: ReactQueryProviderConfig
|
||||
}>;
|
||||
|
||||
export interface ReactQueryProviderConfig {
|
||||
retry?: number;
|
||||
retryDelay?: (attempt: number) => number;
|
||||
staleTime?: number;
|
||||
cacheTime?: number;
|
||||
refetchAllOnWindowFocus?: boolean;
|
||||
refetchInterval?: false | number;
|
||||
suspense?: boolean;
|
||||
export interface IdleMutationResult<TResult> extends MutationResultBase<TResult> {
|
||||
status: 'idle';
|
||||
data: undefined;
|
||||
error: null;
|
||||
}
|
||||
|
||||
export function clearQueryCache(): void;
|
||||
export interface LoadingMutationResult<TResult> extends MutationResultBase<TResult> {
|
||||
status: 'loading';
|
||||
data: undefined;
|
||||
error: undefined;
|
||||
}
|
||||
|
||||
export interface ErrorMutationResult<TResult> extends MutationResultBase<TResult> {
|
||||
status: 'error';
|
||||
data: undefined;
|
||||
error: unknown;
|
||||
}
|
||||
|
||||
export interface SuccessMutationResult<TResult> extends MutationResultBase<TResult> {
|
||||
status: 'success';
|
||||
data: TResult;
|
||||
error: undefined;
|
||||
}
|
||||
|
||||
export type MutationResult<TResult> =
|
||||
| IdleMutationResult<TResult>
|
||||
| LoadingMutationResult<TResult>
|
||||
| ErrorMutationResult<TResult>
|
||||
| SuccessMutationResult<TResult>;
|
||||
|
||||
export interface CachedQuery {
|
||||
queryKey: AnyQueryKey;
|
||||
queryVariables: AnyVariables;
|
||||
queryFn: (...args: any[]) => unknown;
|
||||
config: QueryOptions<unknown>;
|
||||
state: unknown;
|
||||
setData(dataOrUpdater: unknown | ((oldData: unknown | undefined) => unknown)): void;
|
||||
}
|
||||
|
||||
export interface QueryCache {
|
||||
prefetchQuery<TResult, TKey extends AnyQueryKey>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: QueryFunction<TResult, TKey>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): Promise<TResult>;
|
||||
|
||||
prefetchQuery<TResult, TKey extends string>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
queryFn: QueryFunction<TResult, [TKey]>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): Promise<TResult>;
|
||||
|
||||
prefetchQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: QueryFunctionWithVariables<TResult, TKey, TVariables>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): Promise<TResult>;
|
||||
|
||||
prefetchQuery<TResult, TKey extends string, TVariables extends AnyVariables>(
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined),
|
||||
variables: TVariables,
|
||||
queryFn: QueryFunctionWithVariables<TResult, [TKey], TVariables>,
|
||||
config?: QueryOptions<TResult>,
|
||||
): Promise<TResult>;
|
||||
|
||||
prefetchQuery<TResult, TKey extends AnyQueryKey, TVariables extends AnyVariables = []>({
|
||||
queryKey,
|
||||
variables,
|
||||
queryFn,
|
||||
config,
|
||||
}: {
|
||||
queryKey: TKey | false | null | undefined | (() => TKey | false | null | undefined);
|
||||
variables?: TVariables;
|
||||
queryFn: QueryFunctionWithVariables<TResult, TKey, TVariables>;
|
||||
config?: QueryOptions<TResult>;
|
||||
}): Promise<TResult>;
|
||||
|
||||
getQueryData(key: AnyQueryKey | string): unknown | undefined;
|
||||
setQueryData(key: AnyQueryKey | string, dataOrUpdater: unknown | ((oldData: unknown | undefined) => unknown)): void;
|
||||
refetchQueries(
|
||||
queryKeyOrPredicateFn: AnyQueryKey | string | ((query: CachedQuery) => boolean),
|
||||
{ exact, throwOnError, force }?: { exact?: boolean; throwOnError?: boolean; force?: boolean },
|
||||
): Promise<void>;
|
||||
removeQueries(
|
||||
queryKeyOrPredicateFn: AnyQueryKey | string | ((query: CachedQuery) => boolean),
|
||||
{ exact }?: { exact?: boolean },
|
||||
): Promise<void>;
|
||||
getQuery(queryKey: AnyQueryKey): CachedQuery | undefined;
|
||||
getQueries(queryKey: AnyQueryKey): CachedQuery[];
|
||||
isFetching: number;
|
||||
subscribe(callback: (queryCache: QueryCache) => void): () => void;
|
||||
clear(): CachedQuery[];
|
||||
}
|
||||
|
||||
export const queryCache: QueryCache;
|
||||
|
||||
/**
|
||||
* A hook that returns the number of the quiries that your application is loading or fetching in the background
|
||||
* (useful for app-wide loading indicators).
|
||||
* @returns the number of the quiries that your application is currently loading or fetching in the background.
|
||||
*/
|
||||
export function useIsFetching(): number;
|
||||
|
||||
export const ReactQueryConfigProvider: React.ComponentType<{
|
||||
config?: ReactQueryProviderConfig;
|
||||
}>;
|
||||
|
||||
export interface ReactQueryProviderConfig extends BaseQueryOptions {
|
||||
/** Defaults to the value of `suspense` if not defined otherwise */
|
||||
useErrorBoundary?: boolean;
|
||||
throwOnError?: boolean;
|
||||
refetchAllOnWindowFocus?: boolean;
|
||||
queryKeySerializerFn?: (
|
||||
queryKey: QueryKeyPart[] | string | false | undefined | (() => QueryKeyPart[] | string | false | undefined),
|
||||
) => [string, QueryKeyPart[]] | [];
|
||||
|
||||
onMutate?: (variables: unknown) => Promise<unknown> | unknown;
|
||||
onSuccess?: (data: unknown, variables?: unknown) => void;
|
||||
onError?: (err: unknown, snapshotValue?: unknown) => void;
|
||||
onSettled?: (data: unknown | undefined, error: unknown | null, snapshotValue?: unknown) => void;
|
||||
}
|
||||
|
||||
export type ConsoleFunction = (...args: any[]) => void;
|
||||
export interface ConsoleObject {
|
||||
log: ConsoleFunction;
|
||||
warn: ConsoleFunction;
|
||||
error: ConsoleFunction;
|
||||
}
|
||||
|
||||
export function setConsole(consoleObject: ConsoleObject): void;
|
||||
|
||||
6
types/react-query/package.json
Normal file
6
types/react-query/package.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"ts-toolbelt": "*"
|
||||
}
|
||||
}
|
||||
@ -1,83 +1,316 @@
|
||||
import { useMutation, useQuery } from "react-query";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
usePaginatedQuery,
|
||||
useInfiniteQuery,
|
||||
useIsFetching,
|
||||
setConsole,
|
||||
ReactQueryProviderConfig,
|
||||
} from 'react-query';
|
||||
|
||||
const queryFn = () => Promise.resolve();
|
||||
function simpleQuery() {
|
||||
// Query - simple case
|
||||
const querySimple = useQuery('todos', () => Promise.resolve('test'));
|
||||
querySimple.data; // $ExpectType string | undefined
|
||||
querySimple.error; // $ExpectType unknown
|
||||
querySimple.isFetching; // $ExpectType boolean
|
||||
querySimple.refetch(); // $ExpectType Promise<string>
|
||||
querySimple.fetchMore; // $ExpectError
|
||||
querySimple.canFetchMore; // $ExpectError
|
||||
querySimple.isFetchingMore; // $ExpectError
|
||||
}
|
||||
|
||||
// Query - simple case
|
||||
const querySimple = useQuery('todos',
|
||||
() => Promise.resolve('test'));
|
||||
querySimple.data; // $ExpectType string | null
|
||||
querySimple.error; // $ExpectType Error | null
|
||||
querySimple.isLoading; // $ExpectType boolean
|
||||
querySimple.refetch(); // $ExpectType Promise<void>
|
||||
queryPaginated.fetchMore; // $ExpectError
|
||||
queryPaginated.canFetchMore; // $ExpectError
|
||||
queryPaginated.isFetchingMore; // $ExpectError
|
||||
function queryWithVariables() {
|
||||
// Query Variables
|
||||
const param = 'test';
|
||||
const queryVariables = useQuery(['todos', { param }, 10], (key, variables, id) =>
|
||||
Promise.resolve(variables.param === 'test'),
|
||||
);
|
||||
|
||||
// Query Variables
|
||||
const param = 'test';
|
||||
const queryVariables = useQuery(['todos', {param}],
|
||||
(variables) => Promise.resolve(variables.param === 'test'));
|
||||
queryVariables.data; // $ExpectType boolean | undefined
|
||||
queryVariables.refetch(); // $ExpectType Promise<boolean>
|
||||
queryVariables.refetch({ force: true }); // $ExpectType Promise<boolean>
|
||||
}
|
||||
|
||||
queryVariables.data; // $ExpectType boolean | null
|
||||
queryVariables.refetch({variables: {param: 'foo'}}); // $ExpectType Promise<void>
|
||||
queryVariables.refetch({variables: {other: 'foo'}}); // $ExpectError
|
||||
function invalidSimpleQuery() {
|
||||
// first element in the key must be a string
|
||||
useQuery([10, 'a'], async (id, key) => id); // $ExpectError
|
||||
}
|
||||
|
||||
// Query with falsey query key
|
||||
useQuery(false && ['foo', { bar: 'baz' }], queryFn);
|
||||
function conditionalQuery(condition: boolean) {
|
||||
const queryFn1 = (name: string, params: { bar: string }) => Promise.resolve(10);
|
||||
const queryFn2 = () => Promise.resolve('test');
|
||||
|
||||
// Query with query key function
|
||||
useQuery(() => ['foo', { bar: 'baz' }], queryFn);
|
||||
// Query with falsey query key
|
||||
useQuery(condition && ['foo', { bar: 'baz' }], queryFn1);
|
||||
useQuery(condition && ['foo', { bar: 'baz' }], queryFn2);
|
||||
useQuery({
|
||||
queryKey: condition && ['foo', { bar: 'baz' }],
|
||||
queryFn: queryFn1,
|
||||
});
|
||||
|
||||
// Query with nested variabes
|
||||
const queryNested = useQuery(['key', {
|
||||
nested: {
|
||||
props: [1, 2]
|
||||
// Query with query key function
|
||||
useQuery(() => ['foo', { bar: 'baz' }], queryFn1);
|
||||
useQuery(() => ['foo', { bar: 'baz' }], queryFn2);
|
||||
}
|
||||
|
||||
function queryWithNestedKey() {
|
||||
// Query with nested variabes
|
||||
const queryNested = useQuery(
|
||||
[
|
||||
'key',
|
||||
{
|
||||
nested: {
|
||||
props: [1, 2],
|
||||
},
|
||||
},
|
||||
],
|
||||
(key, variables) => Promise.resolve(variables.nested.props[0]),
|
||||
);
|
||||
queryNested.data; // $ExpectType number | undefined
|
||||
}
|
||||
|
||||
function queryWithComplexKeysAndVariables() {
|
||||
useQuery(['key', { a: 1 }], [{ b: { x: 1 } }, { c: { x: 1 } }], (
|
||||
key1, // $ExpectType string
|
||||
key2, // ExpectType { a: number }
|
||||
var1, // $ExpectType { b: { x: number; }; }
|
||||
var2, // $ExpectType { c: { x: number; }; }
|
||||
) => Promise.resolve(key1 === 'key' && key2.a === 1 && var1.b.x === 1 && var2.c.x === 1));
|
||||
|
||||
// custom key
|
||||
const longKey: [string, ...number[]] = ['key', 1, 2, 3, 4, 5];
|
||||
useQuery(
|
||||
longKey,
|
||||
async (
|
||||
key, // $ExpectType string
|
||||
...ids // $ExpectType number[]
|
||||
) => 100,
|
||||
).data; // $ExpectType number | undefined
|
||||
|
||||
const longVariables: [boolean, ...object[]] = [true, {}];
|
||||
useQuery(
|
||||
['key'],
|
||||
longVariables,
|
||||
async (
|
||||
key, // $ExpectType string
|
||||
var1, // $ExpectType boolean
|
||||
...vars // $ExpectType object[]
|
||||
) => 100,
|
||||
).data; // $ExpectType number | undefined
|
||||
|
||||
// the following example cannot work properly, as it would require concatenating tuples with infinite tails.
|
||||
// ts-toolbelt library's `List.Concat` cannot do the job. It would be possible to do with `typescript-tuple` and additional trick.
|
||||
// useQuery<number, typeof longKey, typeof longVariables>(longKey, longVariables, async (
|
||||
// key, // $ExpectType string // <-- currently boolean?!
|
||||
// keyOrVar, // $ExpectType number | boolean // <-- currently object
|
||||
// ...rest // $ExpectType number | object // <-- currently object[]
|
||||
// ) => 100).data; // $ExpectType number | undefined
|
||||
}
|
||||
|
||||
function paginatedQuery() {
|
||||
// Paginated mode
|
||||
const queryPaginated = usePaginatedQuery('key', () => Promise.resolve({ data: [1, 2, 3], next: true }), {
|
||||
refetchInterval: 1000,
|
||||
});
|
||||
queryPaginated.resolvedData; // $ExpectType { data: number[]; next: boolean; } | undefined
|
||||
queryPaginated.latestData; // $ExpectType { data: number[]; next: boolean; } | undefined
|
||||
queryPaginated.data; // $ExpectError
|
||||
|
||||
// Discriminated union over status
|
||||
if (queryPaginated.status === 'loading') {
|
||||
queryPaginated.resolvedData; // $ExpectType { data: number[]; next: boolean; } | undefined
|
||||
queryPaginated.latestData; // $ExpectType { data: number[]; next: boolean; } | undefined
|
||||
queryPaginated.error; // $ExpectType unknown
|
||||
}
|
||||
}], (variables) => Promise.resolve(variables.nested.props[0]));
|
||||
queryNested.data; // $ExpectType number | null
|
||||
|
||||
// Paginated mode
|
||||
const queryPaginated = useQuery('key', () => Promise.resolve({data: [1, 2, 3], next: true}), {
|
||||
refetchInterval: 1000,
|
||||
paginated: true,
|
||||
getCanFetchMore: (lastPage, allPages) => lastPage.next
|
||||
});
|
||||
queryPaginated.data; // $ExpectType { data: number[]; next: boolean; }[] | null
|
||||
queryPaginated.fetchMore; // $ExpectType (variables?: {} | undefined) => Promise<{ data: number[]; next: boolean; }> || (variables?: object | undefined) => Promise<{ data: number[]; next: boolean; }>
|
||||
queryPaginated.canFetchMore; // $ExpectType boolean
|
||||
queryPaginated.isFetchingMore; // $ExpectType boolean
|
||||
if (queryPaginated.status === 'error') {
|
||||
queryPaginated.resolvedData; // $ExpectType { data: number[]; next: boolean; } | undefined
|
||||
queryPaginated.latestData; // $ExpectType { data: number[]; next: boolean; } | undefined
|
||||
queryPaginated.error; // $ExpectType unknown
|
||||
}
|
||||
|
||||
// Paginated mode - check if getCanFetchMore is required
|
||||
useQuery('key', () => Promise.resolve(), {paginated: true}); // $ExpectError
|
||||
if (queryPaginated.status === 'success') {
|
||||
queryPaginated.resolvedData; // $ExpectType { data: number[]; next: boolean; }
|
||||
queryPaginated.latestData; // $ExpectType { data: number[]; next: boolean; }
|
||||
queryPaginated.error; // $ExpectType null
|
||||
}
|
||||
}
|
||||
|
||||
// Simple mutation
|
||||
const mutation = () => Promise.resolve(['foo', 1]);
|
||||
function simpleInfiniteQuery(condition: boolean) {
|
||||
async function fetchWithCursor(key: string, cursor?: string) {
|
||||
return [1, 2, 3];
|
||||
}
|
||||
function getFetchMore(last: number[], all: number[][]) {
|
||||
return last.length ? String(all.length + 1) : false;
|
||||
}
|
||||
|
||||
const [mutate] = useMutation(mutation, {
|
||||
refetchQueries: ['todos', ['todo', { id: 5 }], 'reminders'],
|
||||
refetchQueriesOnFailure: false
|
||||
});
|
||||
mutate();
|
||||
mutate(undefined, {
|
||||
updateQuery: 'query',
|
||||
waitForRefetchQueries: false
|
||||
});
|
||||
useInfiniteQuery<number[], [string], string>(['key'], fetchWithCursor, {
|
||||
getFetchMore: (
|
||||
last, // $ExpectType number[]
|
||||
all, // $ExpectType number[][]
|
||||
) => 'next',
|
||||
});
|
||||
useInfiniteQuery(['key'], fetchWithCursor, { getFetchMore });
|
||||
useInfiniteQuery('key', fetchWithCursor, { getFetchMore });
|
||||
useInfiniteQuery(() => condition && 'key', fetchWithCursor, { getFetchMore });
|
||||
|
||||
// Invalid mutatation funciton
|
||||
useMutation((arg1: string, arg2: string) => Promise.resolve()); // $ExpectError
|
||||
useMutation((arg1: string) => null); // $ExpectError
|
||||
const infiniteQuery = useInfiniteQuery(['key'], fetchWithCursor, { getFetchMore });
|
||||
|
||||
// Mutation with variables
|
||||
const [mutateWithVars] = useMutation(
|
||||
({param}: {param: number}) => Promise.resolve(Boolean(param)),
|
||||
{
|
||||
refetchQueries: ['todos', ['todo', { id: 5 }], 'reminders'],
|
||||
refetchQueriesOnFailure: false
|
||||
});
|
||||
// The next example does not work; the type for cursor does not get inferred.
|
||||
// useInfiniteQuery(['key'], fetchWithCursor, {
|
||||
// getFetchMore: (last, all) => 'string',
|
||||
// });
|
||||
|
||||
mutateWithVars({param: 1}, {
|
||||
updateQuery: 'query',
|
||||
waitForRefetchQueries: false
|
||||
});
|
||||
infiniteQuery.data; // $ExpectType number[][]
|
||||
infiniteQuery.fetchMore(); // $ExpectType Promise<number[][]> | undefined
|
||||
infiniteQuery.fetchMore('next'); // $ExpectType Promise<number[][]> | undefined
|
||||
}
|
||||
|
||||
mutateWithVars({param: 'test'}); // $ExpectError
|
||||
function log(...args: any[]) {}
|
||||
|
||||
function infiniteQueryWithVariables(condition: boolean) {
|
||||
async function fetchWithCursor2(key: string, debuglog?: (...args: any[]) => void, cursor?: string) {
|
||||
if (debuglog) debuglog(key, cursor);
|
||||
return [1, 2, 3];
|
||||
}
|
||||
function getFetchMore(last: number[], all: number[][]) {
|
||||
return last.length ? String(all.length + 1) : false;
|
||||
}
|
||||
|
||||
useInfiniteQuery<number[], [string], [undefined | ((...args: any[]) => void)], string>(
|
||||
['key'],
|
||||
[undefined],
|
||||
fetchWithCursor2,
|
||||
{
|
||||
getFetchMore: (last, all) => 'next',
|
||||
},
|
||||
);
|
||||
|
||||
useInfiniteQuery(['key'], [log], fetchWithCursor2, { getFetchMore });
|
||||
useInfiniteQuery('key', [log], fetchWithCursor2, { getFetchMore });
|
||||
useInfiniteQuery(() => condition && 'key', [log], fetchWithCursor2, { getFetchMore });
|
||||
}
|
||||
|
||||
function simpleMutation() {
|
||||
// Simple mutation
|
||||
const mutation = () => Promise.resolve(['foo', 'bar']);
|
||||
|
||||
const [mutate] = useMutation(mutation, {
|
||||
onSuccess(result) {
|
||||
result; // $ExpectType string[]
|
||||
},
|
||||
});
|
||||
mutate();
|
||||
mutate(undefined, {
|
||||
throwOnError: true,
|
||||
onSettled(result, error) {
|
||||
result; // $ExpectType string[] | undefined
|
||||
error; // $ExpectType unknown
|
||||
},
|
||||
});
|
||||
|
||||
// Invalid mutatation funciton
|
||||
useMutation((arg1: string, arg2: string) => Promise.resolve()); // $ExpectError
|
||||
useMutation((arg1: string) => null); // $ExpectError
|
||||
}
|
||||
|
||||
function mutationWithVariables() {
|
||||
// Mutation with variables
|
||||
const [mutateWithVars] = useMutation(({ param }: { param: number }) => Promise.resolve(Boolean(param)), {
|
||||
useErrorBoundary: true,
|
||||
onMutate(variables) {
|
||||
variables; // $ExpectType { param: number; }
|
||||
return { snapshot: variables.param };
|
||||
},
|
||||
});
|
||||
|
||||
mutateWithVars(
|
||||
{ param: 1 },
|
||||
{
|
||||
async onSuccess(data) {
|
||||
data; // $ExpectType boolean
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
mutateWithVars({ param: 'test' }); // $ExpectError
|
||||
}
|
||||
|
||||
function helpers() {
|
||||
useIsFetching(); // $ExpectType number
|
||||
|
||||
setConsole({ log, error: log, warn: log });
|
||||
}
|
||||
|
||||
function globalConfig() {
|
||||
const globalConfig: ReactQueryProviderConfig = {
|
||||
onError(err, snapshot) {
|
||||
log('Error', err, snapshot);
|
||||
},
|
||||
onMutate(variables) {
|
||||
log(variables);
|
||||
},
|
||||
suspense: true,
|
||||
};
|
||||
}
|
||||
|
||||
function dataDiscriminatedUnion() {
|
||||
// Query Variables
|
||||
const param = 'test';
|
||||
const queryResult = useQuery(['todos', { param }], (key, variables) => Promise.resolve([param]));
|
||||
|
||||
queryResult.data; // $ExpectType string[] | undefined
|
||||
|
||||
// Discriminated union over status
|
||||
if (queryResult.status === 'loading') {
|
||||
queryResult.data; // $ExpectType string[] | undefined
|
||||
queryResult.error; // $ExpectType unknown
|
||||
}
|
||||
|
||||
if (queryResult.status === 'error') {
|
||||
// disabled
|
||||
queryResult.data; // $ExpectType string[] | undefined
|
||||
queryResult.error; // $ExpectType unknown
|
||||
}
|
||||
|
||||
if (queryResult.status === 'success') {
|
||||
// disabled
|
||||
queryResult.data; // $ExpectType string[]
|
||||
queryResult.error; // $ExpectType null
|
||||
}
|
||||
}
|
||||
|
||||
function mutationStatusDiscriminatedUnion() {
|
||||
const mutation = () => Promise.resolve(['foo', 'bar']);
|
||||
const [mutate, mutationState] = useMutation(mutation);
|
||||
mutate();
|
||||
// enabled
|
||||
// TODO: handle invalid argument passed to mutationFn
|
||||
// mutate('arg'); // $ExpectError
|
||||
mutate('arg'); // $ExpectError
|
||||
mutationState.data; // $ExpectType string[] | undefined
|
||||
|
||||
// Discriminated union over status
|
||||
if (mutationState.status === 'idle') {
|
||||
mutationState.data; // $ExpectType undefined
|
||||
mutationState.error; // $ExpectType null
|
||||
}
|
||||
|
||||
if (mutationState.status === 'loading') {
|
||||
mutationState.data; // $ExpectType undefined
|
||||
// corrected
|
||||
// mutationState.error; // $ExpectType null
|
||||
mutationState.error; // $ExpectType undefined
|
||||
}
|
||||
|
||||
if (mutationState.status === 'error') {
|
||||
mutationState.data; // $ExpectType undefined
|
||||
mutationState.error; // $ExpectType unknown
|
||||
}
|
||||
|
||||
if (mutationState.status === 'success') {
|
||||
mutationState.data; // $ExpectType string[]
|
||||
mutationState.error; // $ExpectType undefined
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user