I'm using createSlice
together with useReducer
.
I'd like the dispatch to be typed properly, that is React.Dispatch<ReducerActions>
.
createSlice
?The following does not work, it resolves to AnyAction
... which is understandable I'd say, as all actions pass through all reducers.
Dispatch<Parameters<typeof slice["reducer"]>[1]>
createSlice
stores the action creators as a keyed object in the property actions
. What we are looking for is the union of the return types of all action creators. We will use a mapped type to get this.
type SliceActions<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => infer A ? A : never;
}[keyof T]
type ActionTypes = SliceActions<typeof slice.actions>
I used the counter example from the doc in this Playground Link and the value of ActionTypes
evaluated to:
type ActionTypes = {
payload: undefined;
type: "counter/increment";
} | {
payload: undefined;
type: "counter/decrement";
} | {
payload: number;
type: "counter/incrementByAmount";
}
When I first wrote this answer (October 2020) the action types were inferred as type: string
rather than specific string literals. With the latest versions of Redux Toolkit and TypeScript (as of March 2023) you actually get the exact types!