我用$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
中定义与键相同的值。
答案 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');
}
}
不幸的是,为了不让Flow抱怨,您必须显式重新键入键。 (从v0.98.0开始,您无法执行listTypes[str] !== undefined
或Object.keys(listTypes).includes(str)
。也许有另一种方法可以使Flow正确地细化str
,而无需显式声明每个键,但是我找不到一个)