Skip to content

Commit 6753973

Browse files
committed
change default ThunkArg of cAT to OptionalUnknown
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.
1 parent 6093e0c commit 6753973

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

etc/redux-toolkit.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export function createAction<P = void, T extends string = string>(type: T): Payl
129129
export function createAction<PA extends PrepareAction<any>, T extends string = string>(type: T, prepareAction: PA): PayloadActionCreator<ReturnType<PA>['payload'], T, PA>;
130130

131131
// @public (undocumented)
132-
export function createAsyncThunk<Returned, ThunkArg = void, ThunkApiConfig extends AsyncThunkConfig = {}>(typePrefix: string, payloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg, ThunkApiConfig>, options?: AsyncThunkOptions<ThunkArg, ThunkApiConfig>): AsyncThunk<Returned, ThunkArg, ThunkApiConfig>;
132+
export function createAsyncThunk<Returned, ThunkArg = OptionalUnknown, ThunkApiConfig extends AsyncThunkConfig = {}>(typePrefix: string, payloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg, ThunkApiConfig>, options?: AsyncThunkOptions<ThunkArg, ThunkApiConfig>): AsyncThunk<Returned, ThunkArg, ThunkApiConfig>;
133133

134134
// @public (undocumented)
135135
export function createEntityAdapter<T>(options?: {

src/createAsyncThunk.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ type AsyncThunkActionCreator<
173173
? () => AsyncThunkAction<Returned, ThunkArg, ThunkApiConfig> // argument contains void
174174
: [void] extends [ThunkArg] // make optional
175175
? (arg?: ThunkArg) => AsyncThunkAction<Returned, ThunkArg, ThunkApiConfig> // argument contains undefined
176+
: [ThunkArg] extends [OptionalUnknown]
177+
? (arg?: unknown) => AsyncThunkAction<Returned, ThunkArg, ThunkApiConfig>
176178
: [undefined] extends [ThunkArg]
177179
? WithStrictNullChecks<
178180
// with strict nullChecks: make optional
@@ -270,8 +272,28 @@ export type AsyncThunk<
270272
typePrefix: string
271273
}
272274

275+
const optionalUnknown = Symbol()
276+
/*
277+
* Since TypeScript 4.0, the following example will cause an error when checking
278+
* JavaScript files (with allowJs & checkJs):
279+
```js
280+
const thunk = createAsyncThunk('', arg => {})
281+
thunk()
282+
// @ts-expect-error Expected 0 arguments, but got 1.ts(2554)
283+
thunk('something')
284+
```
285+
* The only way around that without breaking too much explicit existing behaviour
286+
* is this type "OptionalUnknown".
287+
* On the flip side, using a payloadcreator without a defined argument, like
288+
```ts
289+
const thunk = createAsyncThunk('', () => {})
290+
```
291+
* will now generate a thunk that can optionally be called with any first argument
292+
* opposed to a thunk that would not accept any argument before.
293+
*/
294+
type OptionalUnknown = { [optionalUnknown]: never }
295+
273296
/**
274-
*
275297
* @param typePrefix
276298
* @param payloadCreator
277299
* @param options
@@ -280,7 +302,7 @@ export type AsyncThunk<
280302
*/
281303
export function createAsyncThunk<
282304
Returned,
283-
ThunkArg = void,
305+
ThunkArg = OptionalUnknown,
284306
ThunkApiConfig extends AsyncThunkConfig = {}
285307
>(
286308
typePrefix: string,

type-tests/files/createAsyncThunk.typetest.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ const defaultDispatch = (() => {}) as ThunkDispatch<{}, any, AnyAction>
213213
{
214214
const asyncThunk = createAsyncThunk('test', () => 0)
215215
expectType<() => any>(asyncThunk)
216-
// @ts-expect-error cannot be called with an argument
216+
// we have to allow anything to be passed in in this case, to allow
217+
// for compatibility with allowJs & checkJS
217218
asyncThunk(0 as any)
218219
}
219220

0 commit comments

Comments
 (0)