0

I am trying to make an interface that has the dispatch function, but I am not using the Redux.

interface DispatchProps {
  dispatch: (action: { type: string }) => void;
}

export function numberAddTwo({ dispatch }: DispatchProps) {
  dispatch({ type: '@addTwoToNumber' })
}

But when I call the function here

const [state, dispatch] = useReducer(reducer, initialState);
<button className="btn" onClick={() => numberAddTwo(dispatch)}>+2</button>

The error appears at the dispatch parameter

Argument of type 'Dispatch<Action>' is not assignable to parameter of type 'DispatchProps'.
  Property 'dispatch' is missing in type 'Dispatch<Action>' but required in type 'DispatchProps'.ts(2345)

I tried to find the Action interface but I guess that is a Generic type.

Vagner Wentz
  • 391
  • 1
  • 7
  • 29

1 Answers1

1

You can use the Dispatch type provided by React for the parameter type and then pass a discriminated union type Action which could contain all the actions that will update the reducer state:

import { Dispatch, useReducer } from "react";

const ADD_TWO_TO_NUMBER = "@addTwoToNumber"

type Action = | { type: typeof ADD_TWO_TO_NUMBER }

function numberAddTwo(dispatch: Dispatch<Action>) {
  dispatch({ type: ADD_TWO_TO_NUMBER })
}

Here's an example of it working together with the app code:

import { Dispatch, useReducer } from "react";

const ADD_TWO_TO_NUMBER = "@addTwoToNumber"

type Action = | { type: typeof ADD_TWO_TO_NUMBER }

type State = { number: number };

function numberAddTwo(dispatch: Dispatch<Action>) {
  dispatch({ type: ADD_TWO_TO_NUMBER })
}

const reducer = (state: State, action: Action) => {
  switch (action.type) {
    case ADD_TWO_TO_NUMBER:
      return { ...state, number: state.number + 2 };
    default:
      return state;
  }
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, { number: 1 })

  return (
    <div className="App">
      {state.number}
      <button className="btn" onClick={() => numberAddTwo(dispatch)}>+2</button>
    </div>
  );
}

ljbc1994
  • 2,044
  • 11
  • 13
  • Why do we need to use the `typeof ADD_TWO_TO_NUMBER` we can not use just the constant that was created? – Vagner Wentz May 10 '21 at 13:11
  • 1
    It's so we can use the string for the literal type so it can be reused rather than having to type out the string again. – ljbc1994 May 10 '21 at 15:06