2017-02-07 50 views
12

我發現我很困惑的目標和lib選項以及它們如何與源代碼支持的功能進行交互。我覺得這些文檔需要改進一點,所以在提出問題之前在這裏提問。需要澄清的目標和lib編譯器選項

我天真地認爲目標指定了輸出代碼運行所需的JS版本(通過添加模塊加載器)。因此,我們可以始終使用TS在源代碼中支持的所有高級JS功能(如對象擴展),並且編譯器會爲我們指定的目標生成合適的代碼。我認爲它手邊有polyfills等,代碼將運行在目標虛擬機上。

但是,lib選項的文檔指定默認庫取決於目標。但是,庫會影響可用的源類型,從而影響我們可以使用的代碼。因此,我們可以使用的源特徵取決於目標。這不像我預料的那樣。我應該說我對lib的理解是,他們用不同的API來打樣,儘管文檔並沒有真正地說出它們的內容。

我可以看到,這裏有一些不依賴於類型和其他類型的語言功能。但目前還不清楚這是否是這種情況的原因之一。

有人可以澄清這一點嗎?

第二個問題是爲什麼當ES6和ES2015通常被記錄爲同一事物時,它們都存在。

感謝

回答

26

(這開始作爲一個評論,但它得到了太久。)

這是一個有點混亂部分,因爲有一些背後的歷史。我沒有資格權威回答這個問題,但由於早期的發展中,我一直在關注打字稿,這是我的理解:

  • --target告訴編譯器包括哪些庫版本在編譯時(例如ES5會給出一個編譯器錯誤如果使用Promise,但ES6會知道所有關於Promise什麼版本的JS是編譯器發出(例如ES5將向下編譯類語法,但ES6會離開它)。
  • --lib稍後添加,可以更好地控制在編譯時使用的庫版本,而無需更改發佈的JS目標。例如,常見問題是您可能包含ES6庫功能的填充,例如Promise,但您希望通過向下編譯class語法來定位ES5瀏覽器。之前--lib是你要麼不得不目標ES6以避免編譯錯誤約Promise,然後用巴貝爾再次下調編譯,或者您可以指定ES5併爲Promise提供自己的類型定義,這樣編譯器不會給你錯誤。現在用--lib就可以簡單地說你的--target ES5--lib ES6,編譯器不會抱怨Promise,但仍然可以下載到ES5。
  • 這兩個選項都不會導致TS發出任何庫polyfills(Promise等),正如您明顯發現的那樣;您有責任提供正確的運行時庫。它只發出一些低級語言兼容性幫助程序,如__extends__awaiter(不同之處在於classasync不僅僅是一個可以在運行時填充的API,它是一種具有語法含義的語言功能)。 --lib選項只是根據您在運行時知道的信息獲取正確級別的編譯檢查的方法。
  • 至於爲什麼同時存在ES6ES2015,這只是因爲ECMAScript更改了名稱,TS留下了舊名稱作爲向後兼容的有效選項。 :)

你會發現很多的這個涵蓋在這些TS問題:

+0

感謝一個很好的答案。所以我發現混淆的根源在於''-target'''做了這兩件事,另外一些語言特性是向下編譯的,而另一些則不是,但確實需要在源代碼中使用lib。 –

+0

這也是回答另一個問題 - 爲什麼地球上你會使用TS和Babel :)因此,一個很好的方式來定位目前許多當前的瀏覽器,目標是ES中的ES6,並將Babel轉換爲ES5。 –