如何为Redux操作定义Flow类型?

时间:2017-08-24 21:10:01

标签: javascript redux flowtype

我正在研究使用Flow键入Redux操作的方法。使用以下定义,它在action actionor和reducer中都有部分工作。自动填充功能会将所有4个操作选为两个位置action.type的可能值。

// @flow
type ModuleActionTypes1 = 'moduleOne/ACTION_ONE' | 'moduleOne/ACTION_TWO';
type ModuleActionTypes2 = 'moduleTwo/ACTION_ONE' | 'moduleTwo/ACTION_TWO';

type ActionTypes = ModuleActionTypes1 | ModuleActionTypes2;

type Action<T> = {
  type: ActionTypes,
  payload: T
};

type Payload = {
  url: string
};

const actionCreator = (url: string): Action<Payload> => {
  return {
    type: 'moduleOne/ACTION_ONE',
    payload: {
      url: url
    }
  };
};

const reducer = (state: string, action: Action<Payload>): string => {

  if(action.type === 'wrong') {
    // action.type cannot be this 
  }

  switch (action.type) {
    case 'moduleOne/ACTION_ONE':
    case 'wrong': // action type cannot be this
      const { url } = action.payload;
      return url;
    default:
      return state;
  }
};

它几乎可以满足我的需求。有两个主要问题:

  1. 切换案例不一定是action.type之一,因此拼写错误可能会漏掉。这表明我应该坚持使用字符串常量。

  2. 当我import type { ModuleActionTypes1 } from '../moduleOne';(而不是在同一个文件中定义它进行测试)时,自动完成功能会停止工作,但是流程报告命令行没有错误。所有文件都包含@flow评论。

  3. 有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

所以,这与你的问题有点不同,但是让我建议这样做有点不同。现在,您的操作类型表明任何有效负载都可以属于任何操作。如果您使用类型仅定义允许的状态,则流程可能会更有帮助。

我不知道你的行为是什么,所以这是一个随机的例子:

type CreatePerson = { type: 'create-person', person: Person };
type DestroyPerson = { type: 'destroy-person', personId: number };
type ChangePersonName = { type: 'change-name', personId: number, name: string }
type PersonActions = CreatePerson | DestroyPerson | ChangePersonName

以这种方式进行设置有助于确保每个Redux操作都具有正确类型的正确数据。在你的减速机中,你仍然可以在action.type上进行切换/选择使用哪种情况。但现在,通过按字符串选择类型,Flow还确切知道操作中存在哪种类型的数据。这可以让您避免Flow无法进行类型检查的转换或不安全解构。​​