Skip to content

Commit c956f1a

Browse files
authored
fix(UseMutationResult): MutationState type allows type narrowing to match useQuery (#2620)
1 parent 0ec2a49 commit c956f1a

File tree

3 files changed

+102
-21
lines changed

3 files changed

+102
-21
lines changed

src/core/mutationObserver.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { QueryClient } from './queryClient'
44
import { Subscribable } from './subscribable'
55
import type {
66
MutateOptions,
7+
MutationObserverBaseResult,
78
MutationObserverResult,
89
MutationObserverOptions,
910
} from './types'
@@ -129,7 +130,12 @@ export class MutationObserver<
129130
? this.currentMutation.state
130131
: getDefaultState<TData, TError, TVariables, TContext>()
131132

132-
this.currentResult = {
133+
const result: MutationObserverBaseResult<
134+
TData,
135+
TError,
136+
TVariables,
137+
TContext
138+
> = {
133139
...state,
134140
isLoading: state.status === 'loading',
135141
isSuccess: state.status === 'success',
@@ -138,6 +144,13 @@ export class MutationObserver<
138144
mutate: this.mutate,
139145
reset: this.reset,
140146
}
147+
148+
this.currentResult = result as MutationObserverResult<
149+
TData,
150+
TError,
151+
TVariables,
152+
TContext
153+
>
141154
}
142155

143156
private notify(options: NotifyOptions) {

src/core/types.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ export type MutateFunction<
567567
options?: MutateOptions<TData, TError, TVariables, TContext>
568568
) => Promise<TData>
569569

570-
export interface MutationObserverResult<
570+
export interface MutationObserverBaseResult<
571571
TData = unknown,
572572
TError = unknown,
573573
TVariables = void,
@@ -581,6 +581,77 @@ export interface MutationObserverResult<
581581
reset: () => void
582582
}
583583

584+
export interface MutationObserverIdleResult<
585+
TData = unknown,
586+
TError = unknown,
587+
TVariables = void,
588+
TContext = unknown
589+
> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
590+
data: undefined
591+
error: null
592+
isError: false
593+
isIdle: true
594+
isLoading: false
595+
isSuccess: false
596+
status: 'idle'
597+
}
598+
599+
export interface MutationObserverLoadingResult<
600+
TData = unknown,
601+
TError = unknown,
602+
TVariables = void,
603+
TContext = unknown
604+
> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
605+
data: undefined
606+
error: null
607+
isError: false
608+
isIdle: false
609+
isLoading: true
610+
isSuccess: false
611+
status: 'loading'
612+
}
613+
614+
export interface MutationObserverErrorResult<
615+
TData = unknown,
616+
TError = unknown,
617+
TVariables = void,
618+
TContext = unknown
619+
> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
620+
data: undefined
621+
error: TError
622+
isError: true
623+
isIdle: false
624+
isLoading: false
625+
isSuccess: false
626+
status: 'error'
627+
}
628+
629+
export interface MutationObserverSuccessResult<
630+
TData = unknown,
631+
TError = unknown,
632+
TVariables = void,
633+
TContext = unknown
634+
> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
635+
data: TData
636+
error: null
637+
isError: false
638+
isIdle: false
639+
isLoading: false
640+
isSuccess: true
641+
status: 'success'
642+
}
643+
644+
export type MutationObserverResult<
645+
TData = unknown,
646+
TError = unknown,
647+
TVariables = void,
648+
TContext = unknown
649+
> =
650+
| MutationObserverIdleResult<TData, TError, TVariables, TContext>
651+
| MutationObserverLoadingResult<TData, TError, TVariables, TContext>
652+
| MutationObserverErrorResult<TData, TError, TVariables, TContext>
653+
| MutationObserverSuccessResult<TData, TError, TVariables, TContext>
654+
584655
export interface DefaultOptions<TError = unknown> {
585656
queries?: QueryObserverOptions<unknown, TError>
586657
mutations?: MutationObserverOptions<unknown, TError, unknown, unknown>

src/react/types.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { RetryValue, RetryDelayValue } from '../core/retryer'
22
import {
33
InfiniteQueryObserverOptions,
44
InfiniteQueryObserverResult,
5-
MutateOptions,
6-
MutationStatus,
5+
MutationObserverResult,
76
MutationKey,
87
QueryObserverOptions,
98
QueryObserverResult,
109
QueryKey,
1110
MutationFunction,
11+
MutateOptions,
1212
} from '../core/types'
1313

1414
export interface UseBaseQueryOptions<
@@ -119,24 +119,21 @@ export type UseMutateAsyncFunction<
119119
options?: MutateOptions<TData, TError, TVariables, TContext>
120120
) => Promise<TData>
121121

122-
export interface UseMutationResult<
122+
export type UseBaseMutationResult<
123123
TData = unknown,
124124
TError = unknown,
125125
TVariables = unknown,
126126
TContext = unknown
127-
> {
128-
context: TContext | undefined
129-
data: TData | undefined
130-
error: TError | null
131-
failureCount: number
132-
isError: boolean
133-
isIdle: boolean
134-
isLoading: boolean
135-
isPaused: boolean
136-
isSuccess: boolean
137-
mutate: UseMutateFunction<TData, TError, TVariables, TContext>
138-
mutateAsync: UseMutateAsyncFunction<TData, TError, TVariables, TContext>
139-
reset: () => void
140-
status: MutationStatus
141-
variables: TVariables | undefined
142-
}
127+
> = Override<
128+
MutationObserverResult<TData, TError, TVariables, TContext>,
129+
{ mutate: UseMutateFunction<TData, TError, TVariables, TContext> }
130+
> & { mutateAsync: UseMutateAsyncFunction<TData, TError, TVariables, TContext> }
131+
132+
export type UseMutationResult<
133+
TData = unknown,
134+
TError = unknown,
135+
TVariables = unknown,
136+
TContext = unknown
137+
> = UseBaseMutationResult<TData, TError, TVariables, TContext>
138+
139+
type Override<A, B> = { [K in keyof A]: K extends keyof B ? B[K] : A[K] }

0 commit comments

Comments
 (0)