如何在Flow.js中通过枚举验证

时间:2019-04-30 10:02:03

标签: javascript flowtype

我用$Keys<typeof obj>定义了一个枚举类型,并在函数中将此类型用作参数类型。

直接使用已定义的枚举(例如loadList('Type1'))调用此函数时,效果很好。

但是当从其他地方读取参数时,例如用户输入或ajax响应,则无法将string?string转换为ListType类型。

如以下代码所述。

/* @flow */

const listTypes = Object.freeze({
  Type1: 'type_1',
  Type2: 'type_2',
  Type3: 'type_3',
});

type ListType = $Keys<typeof listTypes>;

function loadList(type: ListType): void {
  return;
}

const type: string = 'Type2';
loadList(type); // fail
loadList((type: ListType)) // still fail

if (listTypes[type]) {
  loadList(type); // continue fail
}

if (listTypes[type]) {
  loadList(listTypes[type]); // pass but should fail
}

因此,只有一种使流通过和枚举均能按预期工作的方法,我应该在listTypes中定义与键相同的值。

这是Try in flow.org

的链接

2 个答案:

答案 0 :(得分:2)

尝试将类型变量的类型从字符串更改为ListType

const type: ListType = 'Type2';

答案 1 :(得分:2)

如果您希望能够转换任意的string(例如window.location.search),则可以编写一个函数将其转换为ListType。例如,

function strToListType(str: string): ListType {
  if (str === 'Type1' || str === 'Type2' || str === 'Type3') {
    return str;
  } else {
    throw new Error('Invalid string');
  }
}

Try Flow

不幸的是,为了不让Flow抱怨,您必须显式重新键入键。 (从v0.98.0开始,您无法执行listTypes[str] !== undefinedObject.keys(listTypes).includes(str)。也许有另一种方法可以使Flow正确地细化str,而无需显式声明每个键,但是我找不到一个)