Flow引发错误,因为它认为
可能会改变数组
// given the definitions of `Node`, `ANode`, and `BNode` from the questionâs second example
function getFirstNodeType(nodes: Array<Node>): string {
const bNode: BNode = {type: 'b', count: 0}
// Mutate the parameter `nodes`. Adding a `BNode` is valid according its type.
nodes.push(bNode);
return nodes[0].type;
}
const nodesSubtype: Array<ANode> = [{type: 'a', value: 'foo'}];
getFirstNodeType(nodesSubtype); // error
Try Flow demo
在运行上述代码之后,
nodesSubtype
会包含一个
BNode
即使它被声明为
ANode
,违反了它的类型。
有两种方法可以让Flow相信你不会改变数组。最清楚的是
代替
Array
具有
$ReadOnlyArray
.
function getFirstNodeType(nodes: $ReadOnlyArray<Node>): string { // use $ReadOnlyArray
return nodes[0].type;
}
const nodesSubtype: Array<ANode> = [{type: 'a', value: 'foo'}];
getFirstNodeType(nodesSubtype); // no error
Try Flow demo
您只需在函数参数类型中进行替换(例如。
nodes
),但如果你喜欢,你可以使用
$只读阵列
它适用于任何地方(例如
).
是最安全的类型解决方案,但您可能不想更改所有现有函数来使用它。在这种情况下,你的选择是
将数组类型转换为
any
为什么?
function getFirstNodeType(nodes: Array<Node>): string {
return nodes[0].type;
}
const nodesSubtype: Array<ANode> = [{type: 'a', value: 'foo'}];
// casting `Array<ANode>` to `Array<Node>` is okay because we know that `getFirstNodeType` wonât actually modify the array
getFirstNodeType(((nodesSubtype: any): Array<Node>));
Try Flow demo
如果你不关心记录问题,你可以省略注释,只将其转换为
任何
getFirstNodeType((nodesSubtype: any));
Try Flow demo
额外资源