React Redux Actions类型安全

时间:2019-10-07 11:02:34

标签: reactjs typescript redux

我有一个简单的反例,通过它我可以解释我的困惑。

Counter.Types

export interface DecrementAction {
  type: typeof Types.DECREMENT;
  decrementBy: number
}

类型

export const Types = {
  DECREMENT :Symbol("DECREMENT")
}

Counter.Action

export const decrementAction = (decrementBy: number): DecrementAction => ({
  type: Types.DECREMENT,
  decrementBy: decrementBy
});

export type CounterActionTypes = DecrementAction;

Counter.Reducer

const counter = (state = INITIAL_STATE, action : CounterActionTypes) => {

  switch (action.type) {
    case Types.DECREMENT:
      return {
        count: state.count - action.decrementBy // this dosen't work ts complains decrementBy present in action

      };
    default:
      return state;
  }

};

如果我将行更改为此count: state.count - (action as DecrementAction).question打字稿,则停止抱怨。

我来自ngrx世界,我们可以直接添加payload.<ref>。我在这里想念什么?我们如何不添加<action as ..>并直接引用action变量。

1 个答案:

答案 0 :(得分:0)

我不认为TypeScript不支持将符号用作联合标识符。您可以只使用字符串:

export const Types = {
  DECREMENT: "DECREMENT",
  INCREMENT: "INCREMENT"
} as const

export interface DecrementAction {
  type: typeof Types.DECREMENT;
  decrementBy: number
}

export interface IncrementAction {
  type: typeof Types.INCREMENT;
  incrementBy: number
}

export const decrementAction = (decrementBy: number): DecrementAction => ({
  type: Types.DECREMENT,
  decrementBy: decrementBy
});

export type CounterActionTypes = DecrementAction | IncrementAction;

const INITIAL_STATE = { count: 0 };

const counter = (state = INITIAL_STATE, action: CounterActionTypes) => {
  switch (action.type) {
    case Types.DECREMENT:
      return {
        count: state.count - action.decrementBy
      };
    default:
      return state;
  }
};

TypeScript playground

另外Types可能是一个枚举:

export enum Types {
  DECREMENT = "DECREMENT",
  INCREMENT = "INCREMENT"
}

那么您就不需要typeof中的type: typeof Types.DECREMENT;

TypeScript playground