function f(a ?: Array<string>) {
a = a || [];
a.map // Here it is ok
return Promise.resolve()
.then(() => a.map) // THROWS, WHY?
}
答案 0 :(得分:3)
Flow的类型改进是保守的。这意味着它invalidates them在无法确定它们将会持有的情况下积极地进行。{/ p>
在这种情况下,Flow会看到a
已被重新分配,因此它不能是null
/ undefined
。但是,它不会进行分析,知道始终将是null
/ undefined
- 就其在此处所知,以后的某些任务可以重新进行将其分配给null
/ undefined
。
它也不知道何时会调用传递给.then
的回调。因此,它保守地使改进无效。
请注意,此问题并非特定于Promise
。只要非const变量应用了一个细化,它就会发生,稍后在闭包中使用它。在封闭内部,细化将被删除。
简单的解决方法是使用const
。然后,Flow知道应用的任何类型细化将始终保持,因为永远不能重新分配变量:
function f(a_ ?: Array<string>) {
const a = a_ || [];
a.map // Here it is ok
return Promise.resolve()
.then(() => a.map) // THROWS, WHY?
}
答案 1 :(得分:-2)
这是因为在你的函数定义中你有:
function f(a ?: Array<string>) {
这意味着a
的类型是一个字符串数组但它可以为空(?:
)。它的值可以为null(或未定义)。
虽然从您的代码中可以看出,a
被null
(或未定义)覆盖,但它被空数组覆盖。但它的类型仍然是一个可以为空的字符串数组。
当编译器尝试编译此行时:
.then(() => a.map) // THROWS, WHY?
它认为a
可能为null(或未定义),因此会报错。
如果删除函数参数类型中的问号?
,编译器会知道a
不能为空,因此可以正常工作!
PS:如果需要,您可以将a = a || [];
移动到调用函数f
的函数。