useContext and useReducer in typescript

Viewed 317

I'm new to typescript and I was implementing react useContext and useReducer. I was following a tutorial but im getting an error of Parameter 'action' implicitly has an 'any' type. In my reducer function.

reducer function

function reducer(state, action) { // error Parameter 'action' implicitly has an 'any' type.
     return { count: state.count + 1 }
}

CountProvider

   const [state, dispatch] = useReducer(reducer, {
    count: 0
   })
2 Answers

You have to specify the type of action as any or do it by generic form. In case you want to structure action you could create an interface.

function reducer(state, action: { [key: string]: string|number }) { // error Parameter 'action' implicitly has an 'any' type.
    return { count: state.count + 1 }
}

First you need to type your acrion creators properly:

Actions.ts

export const increment = (
  background: string
): {
  type: "INCREMENT";
  payload: {
    background: string;
  };
} => ({
  type: "INCREMENT",
  payload: {
    background
  }
});

export const decrement = (
  background: string
): {
  type: "DECREMENT";
  payload: {
    background: string;
  };
} => ({
  type: "DECREMENT",
  payload: {
    background
  }
});

export type Action =
  | ReturnType<typeof increment>
  | ReturnType<typeof increment>;

Then in your reducer you should import the type for your actions:

Reducer.ts

import type { Action } from "./actions";

export const initialState = {
  count: 0
};

export type Store = typeof initialState;

export const reducer = (state: Store, action: Action) => {
  switch (action.type) {
    case "INCREMENT":
      return { count: state.count + 1 };
    default:
      return state;
  }
};

And lastly for typing your useReducer hook anywhere in your app:

CountProvider

import type { Store } from "./context/reducer";
import type { Action } from "./context/actions";

const [state, dispatch] = useReducer<React.Reducer<Store, Action>>(
    reducer,
    initialState
  );

You can read more about this here: Elegantly type React’s useReducer and Context API with discriminated union of Typescript

Related