diff --git a/etc/redux-toolkit.api.md b/etc/redux-toolkit.api.md
index 700363d48d..a7167b7c3f 100644
--- a/etc/redux-toolkit.api.md
+++ b/etc/redux-toolkit.api.md
@@ -102,8 +102,13 @@ export function createAction
(type: T): Payl
export function createAction, T extends string = string>(type: T, prepareAction: PA): PayloadActionCreator['payload'], T, PA>;
// @alpha (undocumented)
-export function createAsyncThunk = AsyncThunksArgs>(type: ActionType, payloadCreator: (args: ActionParams, thunkArgs: TA) => Promise | Returned): {
- (args: ActionParams): (dispatch: TA["dispatch"], getState: TA["getState"], extra: TA["extra"]) => Promise;
+export function createAsyncThunk = AsyncThunksArgs>(type: ActionType, payloadCreator: (args: ActionParams, thunkArgs: TA) => Promise | Returned): ((args: ActionParams) => (dispatch: TA["dispatch"], getState: TA["getState"], extra: TA["extra"]) => Promise | import("./createAction").PayloadAction>) & {
pending: import("./createAction").ActionCreatorWithPreparedPayload<[string, ActionParams], undefined, string, never, {
args: ActionParams;
requestId: string;
diff --git a/src/createAsyncThunk.ts b/src/createAsyncThunk.ts
index 944b894f25..39713b7e97 100644
--- a/src/createAsyncThunk.ts
+++ b/src/createAsyncThunk.ts
@@ -101,34 +101,33 @@ export function createAsyncThunk<
) => {
const requestId = nanoid()
- let result: Returned
+ let finalAction: ReturnType
try {
dispatch(pending(requestId, args))
- result = (await payloadCreator(args, {
- dispatch,
- getState,
- extra,
- requestId
- } as TA)) as Returned
+ finalAction = fulfilled(
+ await payloadCreator(args, {
+ dispatch,
+ getState,
+ extra,
+ requestId
+ } as TA),
+ requestId,
+ args
+ )
} catch (err) {
const serializedError = miniSerializeError(err)
- dispatch(rejected(serializedError, requestId, args))
- // Rethrow this so the user can handle if desired
- throw err
+ finalAction = rejected(serializedError, requestId, args)
}
// We dispatch "success" _after_ the catch, to avoid having any errors
// here get swallowed by the try/catch block,
// per https://twitter.com/dan_abramov/status/770914221638942720
// and https://redux-toolkit.js.org/tutorials/advanced-tutorial#async-error-handling-logic-in-thunks
- return dispatch(fulfilled(result!, requestId, args))
+ dispatch(finalAction)
+ return finalAction
}
}
- actionCreator.pending = pending
- actionCreator.rejected = rejected
- actionCreator.fulfilled = fulfilled
-
- return actionCreator
+ return Object.assign(actionCreator, { pending, rejected, fulfilled })
}
diff --git a/type-tests/files/createAsyncThunk.typetest.ts b/type-tests/files/createAsyncThunk.typetest.ts
index 8badad5d5d..b50b81f472 100644
--- a/type-tests/files/createAsyncThunk.typetest.ts
+++ b/type-tests/files/createAsyncThunk.typetest.ts
@@ -1,4 +1,4 @@
-import { createAsyncThunk, Dispatch, createReducer } from 'src'
+import { createAsyncThunk, Dispatch, createReducer, AnyAction } from 'src'
import { ThunkDispatch } from 'redux-thunk'
function expectType(t: T) {
@@ -7,20 +7,37 @@ function expectType(t: T) {
function fn() {}
// basic usage
-{
- const dispatch = fn as ThunkDispatch
+;(async function() {
+ const dispatch = fn as ThunkDispatch<{}, any, AnyAction>
const async = createAsyncThunk('test', (id: number) =>
Promise.resolve(id * 2)
)
- dispatch(async(3))
const reducer = createReducer({}, builder =>
builder
- .addCase(async.pending, (_, action) => {})
+ .addCase(async.pending, (_, action) => {
+ expectType>(action)
+ })
.addCase(async.fulfilled, (_, action) => {
+ expectType>(action)
expectType(action.payload)
})
- .addCase(async.rejected, (_, action) => {})
+ .addCase(async.rejected, (_, action) => {
+ expectType>(action)
+ expectType(action.error)
+ })
)
-}
+
+ const result = await dispatch(async(3))
+
+ if (async.fulfilled.match(result)) {
+ expectType>(result)
+ // typings:expect-error
+ expectType>(result)
+ } else {
+ expectType>(result)
+ // typings:expect-error
+ expectType>(result)
+ }
+})()