Flow无法看到我的数组不是空的?

时间:2017-11-10 08:11:53

标签: flowtype

考虑以下代码:

const size = 500
const indexes = new Array(size).fill(0).map((_,idx) => idx)
let vals 
if (!vals) {
  vals = new Array(size).fill(0)
}
indexes.forEach(v => vals[v]++)
  

注意:我理解这段代码可能看起来很奇怪。 forEaching一个数组(索引)并使用value作为另一个(vals)的索引可能不常见。但它确实有效,我只是试图用一个真实用例的简单案例。

Flow返回此错误:

indexes.forEach(v => vals[v]++)
                    ^ access of computed property/element. Computed property/element cannot be accessed on possibly undefined value
indexes.forEach(v => vals[v]++)
                    ^ uninitialized variable

(您可以在flow.org/try上尝试)

要删除错误,我必须更改最后一行以验证每次迭代的val:

indexes.forEach(v => vals && vals[v] && vals[v]++)

如果我将vals声明替换为立即初始化的内容,那么错误也会消失

let vals = new Array(size).fill(0)

(因此使用数组值作为另一个数组的索引似乎不是问题)

不应该能够理解定义了val吗?

感谢您的任何建议。

2 个答案:

答案 0 :(得分:1)

Flow可能无法推断该级别的值,因此您可以这样做

const size = 500
let vals 
if (!vals) {
  vals = new Array(size).fill(0)
}
let newVals = vals
vals.map(v => newVals[v]++)

答案 1 :(得分:0)

这里的问题不是因为flow认为数组是空的。这是因为flow假定条件初始化实际上是条件,而你知道if分支将永远执行。

Flow正在查看类型,而不是值。 (即使在编译时可以知道某些值)

就流量而言,

if (<boolean expression here>) {
  vals = new Array(size).fill(0)
}

可能会也可能不会初始化vals

最简单的解决方案是删除不必要的if,以明确vals始终初始化:

const size = 500
const indexes = new Array(size).fill(0).map((_,idx) => idx)
let vals 
//if (!vals) {
  vals = new Array(size).fill(0)
//}
indexes.forEach(v => vals[v]++)

Try it here

甚至更好:

const size = 500
const indexes = new Array(size).fill(0).map((_,idx) => idx)
const vals = new Array(size).fill(0)
indexes.forEach(v => vals[v]++)

Try it here