我想使用一个变量来验证数组。所以我这样做了:
const length = array ? array.length : 0;
if (length) {
array.map(_ => _.displayName);
}
为此,我遇到了流错误:Cannot call 'array.map' because property
地图is missing in undefined [1].Flow(InferError)
答案 0 :(得分:0)
在不知道array
类型的情况下很难说出您要做什么。
如果将检查放入变量中,为什么流程会抱怨?
作为一般规则,这无法顺畅进行。流的细化非常有限。 documentation on refinement基本上列出了受支持的每种优化形式,而检查length
不是其中之一。您无法真正做到将某物是某种类型的事实带到后来。看,例如:
// Let's assume `array` is `Array<any> | null` for the sake of this example
const array: Array<any> | null = ([]: any);
我们可以通过以下操作将array
精炼为一个数组:
if (Array.isArray(array)) {
// here, _within this block,_ `array` is of type `Array<any>`
(array: Array<any>);
}
// Here, `array` is `Array<any> | null` again
(array: Array<any>); // Error! Cannot cast `array` to array type
// because null [1] is incompatible with array type [2].
我们也可以做相反的事情:
if (array === null) {
// here, array is `null`
(array: null);
} else {
// and because this is in an `else` block, flow knows that
// array is `Array<any>` here
(array: Array<any>);
}
// ...and now it's back to `Array<any> | null` again:
(array: null); // Error! Cannot cast...
因为我们的工会只有两种选择,一个真实的选择
还有一个假的,我们可以检查array
的真实性
完善它:
if (array) {
(array: Array<any>);
} else {
(array: null);
}
那我们不能做的事情呢?
流程不够聪明,无法理解arrayIsArray
包含有关精炼array
的信息:
const arrayIsArray = Array.isArray(array);
if (arrayIsArray) {
(array: Array<any>); // Error! Cannot cast...
}
一般而言,优化范围仅限于 声明它们出现在其中。
(Try Flow)