code.cycling
code.cycling

Reputation: 1274

useContext and useReducer in typescript

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
   })

Upvotes: 2

Views: 808

Answers (2)

Mohsen Taleb
Mohsen Taleb

Reputation: 1077

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

Upvotes: 0

Jose Rojas
Jose Rojas

Reputation: 3530

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 }
}

Upvotes: 2

Related Questions