Flow 抱怨类型不兼容,即使我先检查类型
Flow complains about type incompatibility even though I check type first
我已经编写了一个 React 下拉组件,我可以向其提供以下任一组件:
string
个数组
- 一组简单的 JSON 对象,每个对象包含
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
returns 文字值的类型,如 here. In the JS code that exists at runtime, such as in your if
statement, typeof
will just tell you whether something is a string, object, etc., as described here 所述。因此,条件运算符的左侧将计算为 "string"
或 "object"
,而不是变量的实际 Flow 类型。
在你的条件右侧,你有 Flow 类型 DropdownMenuIconAndTextType
,它只存在于类型检查时,不存在于运行时。我有点惊讶 Flow 没有因此给你一个错误。
尝试这样的事情:
if(typeof currItem !== 'string'){
convertedItems.push(currItem);
}
这将检查运行时存在的值是字符串还是对象,这应该与 Flow 的类型优化一起使用。
我已经编写了一个 React 下拉组件,我可以向其提供以下任一组件:
string
个数组- 一组简单的 JSON 对象,每个对象包含
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
returns 文字值的类型,如 here. In the JS code that exists at runtime, such as in your if
statement, typeof
will just tell you whether something is a string, object, etc., as described here 所述。因此,条件运算符的左侧将计算为 "string"
或 "object"
,而不是变量的实际 Flow 类型。
在你的条件右侧,你有 Flow 类型 DropdownMenuIconAndTextType
,它只存在于类型检查时,不存在于运行时。我有点惊讶 Flow 没有因此给你一个错误。
尝试这样的事情:
if(typeof currItem !== 'string'){
convertedItems.push(currItem);
}
这将检查运行时存在的值是字符串还是对象,这应该与 Flow 的类型优化一起使用。