如何避免使用文字字符串来缩小流中不相交的联合

时间:2016-10-16 23:32:05

标签: redux flowtype

我在网上找到的所有缩小flowtype中不相交联合的例子都使用了字符串文字,比如the official one。我想知道是否有办法检查枚举中的值,如:

const ACTION_A = 'LITERAL_STRING_A';
const ACTION_B = 'LITERAL_STRING_B';

type ActionA = {
  // This is not allowed
  type: ACTION_A,
  // type: 'LITERAL_STRING_A' is allowed
  dataA: ActionAData,
}

type ActionB = {
  // This is not allowed
  type: ACTION_B,
  // type: 'LITERAL_STRING_B' is allowed
  dataB: ActionBData,
}

type Action = ActionA | ActionB;

function reducer(state: State, action: Action): State {
  // Want to narrow Action to ActionA or ActionB based on type
  switch (action.type) {
    // case 'LITERAL_STRING_A': -- successfully narrow the type
    case ACTION_A: // doesn't work
      // action.dataA is accessible
      ...
  }
  ...
}

不幸的是,你不能这样做,因为字符串不符合类型注释。

如果还有其他方法可以在任何地方强制输入字符串文字,我很乐意知道。

如果没有解决方法,也接受更高层次的建议如何不需要为redux操作定义这些不相交的集合。

2 个答案:

答案 0 :(得分:0)

我现在不是最好的形状,如果我错误地读了你的问题,那就很抱歉。无论如何,我会尽力帮助。这是你正在寻找的吗?

const actionTypes = {
  FOO: 'FOO',
  BAR: 'BAR'
}

type ActionType = $Keys<actionTypes> // one of FOO, BAR

function buzz(actionType: ActionType) {
  switch(actionType) {
    case actionTypes.FOO:
      // blah
  }

这应该有效。对不起,如果我的语法有点偏。

如果你问如何避免在type Action = ActionA | ActionB中列出所有操作类型,那么抱歉,我不知道,我认为这就是你这样做的方式。如果我没记错的话,最近在Flow中引入了一个更好的定义长联合的语法:

type Action =
  | ActionA
  | ActionB
  | ActionC

此外,如果您不需要单独的操作类型,则可以执行

type Action =
  | {type: ACTION_A; dataA: ActionAData;}
  | {type: ACTION_B; dataB: ActionBData;}

答案 1 :(得分:0)

更好的方法是将字符串文字类型用于const值:

Try flow...

const ACTION_A:'LITERAL_STRING_A' = 'LITERAL_STRING_A';
const ACTION_B:'LITERAL_STRING_B' = 'LITERAL_STRING_B';

flow example