This release makes several noticeable changes to the alpha createEntityAdapter
and createAsyncThunk
APIs that were introduced in v1.3.0-alpha.0.
Changes
createEntityAdapter
We made several changes to the type definitions for EntityAdapter
and its related types:
- Replaced separate overloads for handling
string
andnumber
IDs with a singletype EntityId = string | number
type, and used that everywhere - Added
EntityAdapter
method type overloads for correct inference ofPayloadAction<T>
when passed directly as a case reducer inside ofcreateSlice
'sreducers
field - Removed the
removeMany(Predicate)
overload, as we discourage passing functions inside of actions
createAsyncThunk
Type Changes
The alpha.0
release was broken when used with TypeScript. If you tried to declare a promise payload callback that took no parameters, our initial types forced TS to assume that the actual thunk action creator took a single arg of type never
, making it impossible to dispatch correctly.
The types that we started from also were overly complex in how they tried to infer arguments and the return value of the promise callback.
We've reworked the createAsyncThunk
types to correctly allow declaring a promise callback with no arguments, and simplified the type inference when there are arguments.
Action Payload Changes
Previously, the result of the promise callback and the arguments to the thunk action creator were passed together in the payload, as payload: {result, args}
This makes it harder to combine the thunk lifecycle actions and the EntityAdapter
reducers together, as the reducers expect the real contents as simply action.payload
. So, we've altered the action definitions so that the fulfilled
action has the promise result as its action.payload
, the rejected
action has the error as action.error
, and the thunk arguments are now in action.meta.args
for all action types.
In addition, we wanted to add some kind of unique request ID to each set of lifecycle actions, to help tie them together if necessary. We now generate a unique ID per call to the thunk, using nanoid
, and include that value as action.meta.requestId
in each action dispatched out of that thunk call. It will also be passed in the options object that is the second argument to the promise callback.
Since we don't have any formal documentation yet, here is the signature of the call to the promise payload creator callback:
const result = (await payloadCreator(args, {
dispatch,
getState,
extra,
requestId
} as TA)) as Returned
and here are the internal action definitions:
const fulfilled = createAction(
type + '/fulfilled',
(result: Returned, requestId: string, args: ActionParams) => {
return {
payload: result,
meta: { args, requestId }
}
}
)
const pending = createAction(
type + '/pending',
(requestId: string, args: ActionParams) => {
return {
payload: undefined,
meta: { args, requestId }
}
}
)
const finished = createAction(
type + '/finished',
(requestId: string, args: ActionParams) => {
return {
payload: undefined,
meta: { args, requestId }
}
}
)
const rejected = createAction(
type + '/rejected',
(error: Error, requestId: string, args: ActionParams) => {
return {
payload: undefined,
error,
meta: { args, requestId }
}
}
)
Removal of TS 3.3 and 3.4 from CI
We've been trying to keep our TS types compatible with multiple TS versions, from 3.3 onwards. We've had to do a number of type workarounds to keep 3.3 compatibility, and it's become painful to keep that going.
Other libraries such as Immer have already jumped up to only supporting TS 3.7+.
For now, we're removing TS 3.3 and 3.4 from our CI runs, and will likely stop supporting them in our library types when 1.3.0 is released.
Example
I've put together a small CodeSandbox that demonstrates use of createSlice
, createEntityAdapter
, and createAsyncThunk
working together in a test:
Redux Toolkit v1.3.0-alpha.1 APIs example