如何将接口键入为Dispatch<Action>?

How type the interface as Dispatch<Action>?

我正在尝试制作一个具有 dispatch 功能的界面,但我没有使用 Redux。

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

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

但是当我在这里调用函数时

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

调度参数出现错误

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)

我试图找到 Action 接口,但我猜那是一个通用类型。

您可以使用 React 提供的 Dispatch 类型作为参数类型,然后传递一个可区分的联合类型 Action,它可以包含所有将更新 reducer 状态的操作:

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

这是它与应用程序代码一起工作的示例:

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