Flow无法识别回调内的细化

时间:2016-04-08 12:52:20

标签: flowtype

此代码通过流程检查:

/* @flow */

function test (list: ?Array<string>): Promise<number> {
  if(list !== null && list !== undefined) {
    return Promise.resolve(list.length)
  } else {
    return Promise.resolve(0)
  }
}

console.log(test(null))

以下获取空检查错误

/* @flow */

function test (list: ?Array<string>): Promise<number> {
  if(list !== null && list !== undefined) {
    return Promise.resolve().then(() => list.length)
  } else {
    return Promise.resolve(0)
  }
}

console.log(test(null))

错误:

property `length`. Property cannot be accessed on possibly null value

显然列表不能是null所以必须有一些代码结构使得流程无法识别这一点。

我想了解我遇到的限制以及如何解决这个问题。谢谢!

1 个答案:

答案 0 :(得分:7)

基本上,Flow不知道您的类型细化(空检查)将在执行() => list.length时保留。在回调流程中,只查看列表的类型 - 它表示它可以为空。

第一个和第二个代码段之间的区别在于,第二个代码段list正在跨越一个函数边界 - 您使用的函数与您改进其类型的函数不同。

一种解决方案是将list.length提取到变量中,并在回调中使用该变量。

var length = list.length;
return Promise.resolve().then(() => length)

这可能也有效:

var list2: Array<string> = list;
return Promise.resolve().then(() => list2.length)

请注意,即使对于立即调用的回调,此问题也存在,例如:使用mapforEach时。关于flow的github有一个问题,但是在快速搜索之后我找不到它。