我已经编写了一个React下拉组件,可以向以下提供以下任何一个选项:
string
s的数组text
和icon
的两个属性。我的简单流类型如下:
type DropdownMenuItemType = DropdownMenuIconAndTextType | string;
type DropdownMenuIconAndTextType ={
text: string,
icon?: React$Element<React$ElementType>;
}
组件的早期版本仅支持字符串。添加元素以支持text
和icon
是我正在实施的新功能请求。我不希望现有用户发生任何重大变化。
因此,在我的组件中,我尝试尝试转换提供的所有string
并将其包装在DropdownMenuIconAndTextType
中,因此所有内容最终都变成了这种类型。已经是“ DropdownMenuIconAndTextType`”的项目保持不变。
let Array<DropdownMenuItemType> originalItems =
let Array<DropdownMenuIconAndTextType> convertedItems = [];
{'English', 'French', 'German', {text: 'Dutch', icon : <SomeIcon />}};
items.forEach( (currItem: DropdownMenuItemType) => {
if(typeof currItem === DropdownMenuIconAndTextType){
convertedItems.push(currItem);
}
else {
convertedItems.push({text: currItem.toString()});
}
});
但是,流程有一个错误:
if(typeof currItem === DropdownMenuIconAndTextType){
convertedItems.push(currItem);
}
[它说currItem
仍可能是string
,并且与convertedItems
不兼容,尽管将其类型检查为DropdownMenuIconAndTextType
。
在这种情况下,我需要怎么做才能满足流程?预先感谢。
我相信您正在混淆Flow的类型代码和JS代码之间的区别。
在类型签名中,typeof
返回文字值的类型,如here所述。在运行时存在的JS代码中,例如if
语句中,typeof
只会告诉您某些东西是字符串,对象等,如here所述。因此,条件运算符的左侧将求值为"string"
或"object"
,而不是变量的实际Flow类型。
在条件的右侧,您具有流类型DropdownMenuIconAndTextType
,仅在类型检查时存在,而在运行时不存在。因此,Flow并没有给您一个错误,我感到很惊讶。
尝试这样的事情:
if(typeof currItem !== 'string'){
convertedItems.push(currItem);
}
这将检查运行时存在的值是字符串还是对象,应该与Flow的类型细化一起使用。