diff --git a/etc/redux-toolkit.api.md b/etc/redux-toolkit.api.md
index d0bd3cf298..5efefa73e2 100644
--- a/etc/redux-toolkit.api.md
+++ b/etc/redux-toolkit.api.md
@@ -129,7 +129,7 @@ export function createAction
(type: T): Payl
export function createAction, T extends string = string>(type: T, prepareAction: PA): PayloadActionCreator['payload'], T, PA>;
// @public (undocumented)
-export function createAsyncThunk(typePrefix: string, payloadCreator: AsyncThunkPayloadCreator, options?: AsyncThunkOptions): AsyncThunk;
+export function createAsyncThunk(typePrefix: string, payloadCreator: AsyncThunkPayloadCreator, options?: AsyncThunkOptions): AsyncThunk;
// @public (undocumented)
export function createEntityAdapter(options?: {
diff --git a/src/createAsyncThunk.ts b/src/createAsyncThunk.ts
index 0642e7a2bf..6568520ccb 100644
--- a/src/createAsyncThunk.ts
+++ b/src/createAsyncThunk.ts
@@ -173,6 +173,8 @@ type AsyncThunkActionCreator<
? () => AsyncThunkAction // argument contains void
: [void] extends [ThunkArg] // make optional
? (arg?: ThunkArg) => AsyncThunkAction // argument contains undefined
+ : [ThunkArg] extends [OptionalUnknown]
+ ? (arg?: unknown) => AsyncThunkAction
: [undefined] extends [ThunkArg]
? WithStrictNullChecks<
// with strict nullChecks: make optional
@@ -270,8 +272,28 @@ export type AsyncThunk<
typePrefix: string
}
+const optionalUnknown = Symbol()
+/*
+ * Since TypeScript 4.0, the following example will cause an error when checking
+ * JavaScript files (with allowJs & checkJs):
+```js
+const thunk = createAsyncThunk('', arg => {})
+thunk()
+// @ts-expect-error Expected 0 arguments, but got 1.ts(2554)
+thunk('something')
+```
+ * The only way around that without breaking too much explicit existing behaviour
+ * is this type "OptionalUnknown".
+ * On the flip side, using a payloadcreator without a defined argument, like
+```ts
+const thunk = createAsyncThunk('', () => {})
+```
+ * will now generate a thunk that can optionally be called with any first argument
+ * opposed to a thunk that would not accept any argument before.
+ */
+type OptionalUnknown = { [optionalUnknown]: never }
+
/**
- *
* @param typePrefix
* @param payloadCreator
* @param options
@@ -280,7 +302,7 @@ export type AsyncThunk<
*/
export function createAsyncThunk<
Returned,
- ThunkArg = void,
+ ThunkArg = OptionalUnknown,
ThunkApiConfig extends AsyncThunkConfig = {}
>(
typePrefix: string,
diff --git a/type-tests/files/createAsyncThunk.typetest.ts b/type-tests/files/createAsyncThunk.typetest.ts
index c93c4dd2bd..0eb839e46a 100644
--- a/type-tests/files/createAsyncThunk.typetest.ts
+++ b/type-tests/files/createAsyncThunk.typetest.ts
@@ -213,7 +213,8 @@ const defaultDispatch = (() => {}) as ThunkDispatch<{}, any, AnyAction>
{
const asyncThunk = createAsyncThunk('test', () => 0)
expectType<() => any>(asyncThunk)
- // @ts-expect-error cannot be called with an argument
+ // we have to allow anything to be passed in in this case, to allow
+ // for compatibility with allowJs & checkJS
asyncThunk(0 as any)
}