【问题标题】:Flow doesn't recognise refinement inside callbackFlow 无法识别回调内部的细化
【发布时间】:2017-12-06 07:10:35
【问题描述】:

这段代码通过了流检查:

/* @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,所以代码结构一定有一些东西让flow无法识别它。

我想了解我遇到了什么限制以及如何解决它。谢谢!

【问题讨论】:

    标签: flowtype


    【解决方案1】:

    基本上,Flow 不知道您的类型优化(空检查)将在执行 () =&gt; list.length 时保持不变。在回调内部,Flow 只查看列表的类型——它表示它可以为空。

    第一个和第二个 sn-p 之间的区别在于,在第二个 sn-p 中 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 上有一个 issue 关于这个,但是我快速搜索后找不到它。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2013-12-13
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多