Skip to content

luisanton-io/safe-redux-actions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

S A F E - R E D U X - A C T I O N S

Easily add typings to your Redux actions.

Install: npm i safe-redux-actions

Live example

1. Create an action maker using createActionMaker

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>();

2. Create the Actions object

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]>;

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published