S A F E - R E D U X - A C T I O N S
Easily add typings to your Redux actions.
npm i safe-redux-actions
Install: Live example
createActionMaker
1. Create an action maker using As a type argument we specify the typeof Actions
.
Note: we still actually need to define the Actions
object
import { createActionMaker } from "safe-redux-actions"
const makeAction = createActionMaker<typeof Actions>();
Actions
object
2. Create the Here we can build the Action
object. Actions
keys are supposed to be corresponding to the action types.
That means the action maker makeAction
will only allow as an argument a string which is also a keyof Actions
.
export const Actions = {
add: (num: number) => makeAction("add", num), // { type: "add", payload: num }
increase: () => makeAction("increase"), // { type: "increase" }
decrease: () => makeAction("decrease") // { type: "decrease" }
};
3. Export the type for any single Action
The exported Action
type will be used as input type for your reducer(s).
The typings for the payload and the action type will be automatically inferred.
import { createActionMaker, SingleAction } from "safe-redux-actions"
//...
export type Action = SingleAction<typeof Actions>;
That's it!
This is how it will look like in your reducer:
import { Action } from "src/store/actions";
export interface CounterState {
counter: number;
}
export const initialState: CounterState = {
counter: 0
};
export default function rootReducer(state = initialState, action: Action) {
switch (action.type) { // "add" | "increase" | "decrease"
case "add":
return {
...state,
counter: state.counter + action.payload // payload is number
};
case "increase":
// payload is unknown
return {
...state,
counter: state.counter + 1
};
case "decrease":
// payload is unknown
return {
...state,
counter: state.counter - 1
};
default:
return state;
}
}
Appendix
The goal of this package was making possible to easily type a basic Redux implementation with as little code as possible.
The following is the actual full code of this package:
export const createActionMaker = <A>() => <T extends keyof A, P>(type: T, payload?: P) => ({ type, payload: payload! });
export type SingleAction<T extends Record<string, (...p: any) => any>> = ReturnType<T[keyof T]>;