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

How to pass enum validation in Flow.js

我通过 $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

的 link

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

const type: ListType = 'Type2';

如果您希望能够转换任意 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,但我找不到一个.)