2017-06-09 14 views
4

可達有一些打字稿代碼看起來基本上像這樣我如何指示的路徑是在TypeScipt

if(...) 
    result = $(document.createElement("div")) ; 
} else if(...) { 
    result = $(document.createElement("div")) ; 
} else { 
    assert.unreachable("Unknown label in buildHTML.") ; 
} 
result.attr("data-childNumber", childNumber.toString()) ; 

assert.unreachable返回類型是never

最後一行顯示「變量結果」在分配前使用時出錯。

在我看來,來自assert.unreachablenever結果應該告訴編譯器,else部分中沒有路徑。

我知道我可以通過在else的末尾添加throw null;來抑制錯誤,但這看起來不雅觀。

unreachable的定義中出現類似的問題。它看起來像這樣

export function unreachable(message? : string) : never { 
    if(message===undefined) message = "Unreachable code reached." ; 
    else message = "Unreachable code reached: "+message ; 
    raiseTheAlarm(message) ; 
} 

其中raiseTheAlarm結果類型爲never。在這種情況下,我得到一個錯誤「一個函數返回'永不'不能達到終點。」

我修正了這個問題,在調用raiseTheAlarm之前加了一個return關鍵字。這看起來有點奇怪。 (當然throw null;通話後也將工作。)

有沒有更好的方式告訴編譯器,代碼中的一個點不可達?

+0

tsc編譯器版本爲2.3.4 –

+0

對'assert.unreachable' *的調用會阻止後續代碼的執行,因爲對'assert.unreachable'函數的調用永遠不會返回。 –

+0

顏色我教育了'永不'類型。我完全錯過了這個功能。對困惑感到抱歉。 – Silvermind

回答

1

在我看來,從assert.unreachable應該不會導致 告訴編譯器,從else部分沒有路徑。

它運作的另一種方式。當編譯器檢測到某個路徑不可訪問時,它會爲該路徑中引用的變量推斷never類型(如果可以)。您可以使用它來強制您的代碼處理枚舉或聯合類型的所有可能值,如解釋here所述。

但是,編譯器不會使用某些路徑無法訪問的信息,因爲它在初始化之前檢查變量沒有被使用。解決方案很簡單 - 您可以將never值分配給不可達路徑中的變量。正如上面回答中所解釋的那樣,never已被分配給專門用於此目的的任何其他類型。

if(...) 
    result = $(document.createElement("div")) ; 
} else if(...) { 
    result = $(document.createElement("div")) ; 
} else { 
    result = assert.unreachable("Unknown label in buildHTML.") ; 
} 
result.attr("data-childNumber", childNumber.toString()) ; 

一個問題,您unreachable功能被固定以同樣的方式 - 它應該有

return raiseTheAlarm(message) ; 

的最後一條語句。

+0

很棒的回答。我有一個狡辯。你說「但是,編譯器不會使用某些路徑無法訪問的信息,因爲它在初始化之前檢查變量沒有被使用。」但是添加'throw null;'來抑制錯誤的事實表明編譯器有時會這樣做。 –

+1

添加'throw'或'return'可以明確地告訴編譯器,在使用之前,不會有'result'未賦值的路徑。一個可能的解釋是[無法訪問的代碼分析是完全獨立於分析之前檢測使用的分析](https://github.com/Microsoft/TypeScript/issues/5207#issuecomment-147469302)他們可能應該在github上有一個問題那。 – artem

1

至少有三個選項

(一)

else { 
    return assert.unreachable("Unknown label in buildHTML.") ; 
} 

(B)(來自@阿爾喬姆的答案)

else { 
    result = assert.unreachable("Unknown label in buildHTML.") ; 
} 

(C)

else { 
    assert.unreachable("Unknown label in buildHTML.") ; 
    throw null ; 
} 

我選擇了(a)。

相關問題