尝试将TypeScript添加到useReducer挂钩时发生解析错误?

时间:2019-07-02 07:06:35

标签: reactjs typescript

我试图了解如何将TypeScript与useReducer挂钩一起使用。这是一个使用常规JavaScript的简单计数器:

function reducer(state, action) {
  switch (action.type) {
    case "+":
      return { ...state, no: state.no + 1}
    case "-":
      return { ...state, no: state.no - 1}
    default:
      throw new Error("All conditions missed");
  }
}

function App() {

  const [state, dispatch] = React.useReducer(reducer, {no: 1})

  return (
    <div className="App">
      <h1>{state.no}</h1>
      <button type="button" onClick={()=>dispatch({type: "-"})}>-</button>
      <button type="button" onClick={()=>dispatch({type: "+"})}>+</button>
    </div>
  );
}

https://codesandbox.io/s/zealous-austin-eog2p

我尝试添加类型,但是遇到解析错误:

interface IState {
  no: string;
}

function reducer(state: IState[], action) {
  switch (action.type) {
    case "+":
      return { ...state, no: state.no + 1}
    case "-":
      return { ...state, no: state.no - 1}
    default:
      throw new Error("All conditions missed");
  }
}

function App() {

  const [state, dispatch] = React.useReducer(reducer, {no: 1}: IState[])

  return (
    <div className="App">
      <h1>{state.no}</h1>
      <button type="button" onClick={()=>dispatch({type: "-"})}>-</button>
      <button type="button" onClick={()=>dispatch({type: "+"})}>+</button>
    </div>
  );
}

https://codesandbox.io/s/patient-forest-1gp88

1 个答案:

答案 0 :(得分:0)

作为参考,useReducer()的签名为

type Reducer<S, A> = (prevState: S, action: A) => S;
type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any> ? S : never;
type ReducerAction<R extends Reducer<any, any>> = R extends Reducer<any, infer A> ? A : never;
type Dispatch<A> = (value: A) => void;
function useReducer<R extends Reducer<any, any>>(
  reducer: R,
  initialState: ReducerState<R>,
  initializer?: undefined,
): [ReducerState<R>, Dispatch<ReducerAction<R>>];

看起来像

interface IState {
  no: number;
}

const reducer: React.Reducer<IState, any> = (state: IState, action) => {
  switch (action.type) {
    case "+":
      return { ...state, no: state.no + 1 };
    case "-":
      return { ...state, no: state.no - 1 };
    default:
      throw new Error("All conditions missed");
  }
};

// ...
const [state, dispatch] = React.useReducer(reducer, { no: 1 });

解析,类型检查并可以正常运行-与您的版本有所不同:

    界面中的
  • no是一个数字(必须输入,以便reducer内的算术和初始状态有意义)。
  • reducer是显式键入的箭头函数。