From 90cec4ec74810e3bbcf0c3c1fbf9781f17611f52 Mon Sep 17 00:00:00 2001 From: MrLoh Date: Mon, 28 Sep 2020 13:12:51 -0500 Subject: [PATCH 1/2] use discriminating union for query result type --- src/core/queryObserver.ts | 2 +- src/core/types.ts | 76 +++++++++++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/core/queryObserver.ts b/src/core/queryObserver.ts index 775111521b..b8eeeb26de 100644 --- a/src/core/queryObserver.ts +++ b/src/core/queryObserver.ts @@ -274,7 +274,7 @@ export class QueryObserver { refetch: this.refetch, remove: this.remove, updatedAt, - } + } as QueryResult } private updateQuery(): void { diff --git a/src/core/types.ts b/src/core/types.ts index af7c9879cf..63c6ab8635 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -185,44 +185,92 @@ export enum QueryStatus { Success = 'success', } -export interface QueryResultBase { +interface QueryResultBaseCommon { canFetchMore: boolean | undefined clear: () => void - data: TResult | undefined - error: TError | null failureCount: number fetchMore: ( fetchMoreVariable?: unknown, options?: FetchMoreOptions ) => Promise - isError: boolean isFetched: boolean isFetchedAfterMount: boolean isFetching: boolean isFetchingMore?: IsFetchingMoreValue - isIdle: boolean isInitialData: boolean - isLoading: boolean isPreviousData: boolean isStale: boolean - isSuccess: boolean refetch: (options?: RefetchOptions) => Promise remove: () => void - status: QueryStatus updatedAt: number } -export interface QueryResult - extends QueryResultBase {} +interface QueryResultBaseIdle extends QueryResultBaseCommon { + status: QueryStatus.Idle + isIdle: true + isLoading: false + isSuccess: false + isError: false + data?: undefined + error: null +} + +interface QueryResultBaseLoading + extends QueryResultBaseCommon { + status: QueryStatus.Loading + isIdle: false + isLoading: true + isSuccess: false + isError: false + data?: undefined + error: null +} + +interface QueryResultBaseSuccess + extends QueryResultBaseCommon { + status: QueryStatus.Success + isIdle: false + isLoading: false + isSuccess: true + isError: false + data: TResult + error: null +} + +interface QueryResultBaseError + extends QueryResultBaseCommon { + status: QueryStatus.Error + isIdle: false + isLoading: false + isSuccess: false + isError: true + data?: undefined + error: TError +} -export interface PaginatedQueryResult - extends QueryResultBase { +export type QueryResultBase = + | QueryResultBaseIdle + | QueryResultBaseLoading + | QueryResultBaseSuccess + | QueryResultBaseError + +export type QueryResult = QueryResultBase< + TResult, + TError +> + +export type PaginatedQueryResult = QueryResultBase< + TResult, + TError +> & { resolvedData: TResult | undefined latestData: TResult | undefined } -export interface InfiniteQueryResult - extends QueryResultBase {} +export type InfiniteQueryResult = QueryResultBase< + TResult[], + TError +> export interface MutateConfig< TResult, From c3c5f15cf68b0fbaeba38ad61341ceb30d97aecc Mon Sep 17 00:00:00 2001 From: MrLoh Date: Mon, 28 Sep 2020 19:07:56 -0500 Subject: [PATCH 2/2] use discriminating union for mutation result type --- src/core/types.ts | 50 +++++++++++++++++++++++++++++++++------- src/react/useMutation.ts | 5 +--- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/core/types.ts b/src/core/types.ts index 63c6ab8635..e9b93a67db 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -327,16 +327,50 @@ export type MutationResultPair = [ MutationResult ] -export interface MutationResult { - status: QueryStatus - data: TResult | undefined - error: TError | null - isIdle: boolean - isLoading: boolean - isSuccess: boolean - isError: boolean +interface MutationResultCommon { reset: () => void } +interface MutationResultIdle extends MutationResultCommon { + status: QueryStatus.Idle + data?: undefined + error?: null + isIdle: true + isLoading: false + isSuccess: false + isError: false +} +interface MutationResultLoading extends MutationResultCommon { + status: QueryStatus.Loading + data?: undefined + error?: null + isIdle: false + isLoading: true + isSuccess: false + isError: false +} +interface MutationResultSuccess extends MutationResultCommon { + status: QueryStatus + data: TResult + error?: null + isIdle: false + isLoading: false + isSuccess: true + isError: false +} +interface MutationResultError extends MutationResultCommon { + status: QueryStatus + data?: undefined + error: TError + isIdle: false + isLoading: false + isSuccess: true + isError: false +} +export type MutationResult = + | MutationResultIdle + | MutationResultLoading + | MutationResultSuccess + | MutationResultError export interface ReactQueryConfig { queries?: ReactQueryQueriesConfig diff --git a/src/react/useMutation.ts b/src/react/useMutation.ts index 2d0a313101..734321b819 100644 --- a/src/react/useMutation.ts +++ b/src/react/useMutation.ts @@ -199,10 +199,7 @@ export function useMutation< dispatch({ type: ActionType.Reset }) }, [dispatch]) - const result: MutationResult = { - ...state, - reset, - } + const result = { ...state, reset } as MutationResult return [mutate, result] }