2017-06-27 86 views

回答

3

Flow的類型細化是保守的。這意味着當它不能確定他們將持有時,它會積極地進行。

在這種情況下,Flow會看到a已重新分配,因此它不得爲null/undefined。然而,它並沒有做分析知道是總是將會是null/undefined - 就其所知,稍後的一些分配可能會將其重新分配給null/undefined

它也不知道什麼時候回調傳遞給.then會被調用。所以,它保守地使提煉無效。

請注意,此問題不是特定於Promise s。每當一個非const變量應用了一個優化時它就會發生,並且稍後將用於閉包。在關閉內部,細化將被丟棄。

簡單的解決方法是使用const。然後,流量知道被應用於任何類型的細化將永遠持有,因爲變量不能被重新分配:

function f(a_ ?: Array<string>) { 
    const a = a_ || []; 
    a.map // Here it is ok 
    return Promise.resolve() 
    .then(() => a.map) // THROWS, WHY? 
} 
-2

那是因爲在你的函數定義「屬性不能在可能未定義的訪問」您有:

function f(a ?: Array<string>) {

這意味着a的類型是字符串數組,但它是可空的?:)。它的值可以爲null(或未定義)。

雖然從您的代碼很明顯,a如果它的null(或未定義)被空數組重寫。但是它的類型仍然是一個可空的字符串數組。

當編譯器試圖編譯這一行:

.then(() => a.map) // THROWS, WHY?

它認爲a可能爲空(或undefined),並以一個錯誤如此抱怨。

如果您刪除函數參數類型中的問號?,編譯器知道a不能爲空,因此它的工作原理!

PS:如果需要,您可以將a = a || [];移動到調用函數f的函數中。

+3

不; Flow非常聰明,知道'a = a || [];'將'a'的類型改進爲不再包含'null'。這就是爲什麼第一個'a.map'很好。問題是這個流程分析不包括閉包。 – SLaks