TypeScript 官方:JavaScript 中直接支援型別!

語言: CN / TW / HK

大家好,我是 零一。TypeScript 團隊在深夜突然發了一條推,神祕兮兮說:“如果我們可以直接在 JavaScript 中支援型別,會怎麼樣?”。

他們在評論區說:“型別作為註釋”的提案意味著瀏覽器可以直接執行通過了 TS 檢查的程式碼(即使它們沒有做任何型別檢查)。這意味著更好的編輯體驗和更快的迭代。

這是一個很讓人興奮的想法,接下來我們具體看看這個提案的內容。

這是一個新的 stage0 的語法提案,暫時還未提交給 TC39。github 的倉庫地址是 https://github.com/giltayar/proposal-types-as-comments

背景

我們團隊最近在 JavaScript 領域看到的一個趨勢是,需要更快的迭代時間和減少構建步驟。換句話說,“更快、更簡單”。

在某種程度上,這已經發生了。多虧了瀏覽器的成功,開發人員通常可以避免編譯較新版本的JavaScript以在較舊的 runtime上執行。在某種程度上,構建也是如此 —— 大多數瀏覽器都內建了對 module 的支援,因此構建漸漸成為了一個優化步驟而不是必要步驟。這種情況下,TypeScript 如何跟進呢?

如果我們回到2012年,TypeScript首次釋出的時候,JavaScript的世界就大不相同了!一些瀏覽器經常更新,但另一些不會。我們還不清楚Internet Explorer的古老版本會持續多久,這導致構建工具和編譯器等工具大行其道。在向JavaScript新增構建步驟的時代,TypeScript能夠蓬勃發展——畢竟,如果你需要編譯JavaScript,為什麼不也順便編譯你的型別呢?但是,如果我們上面提到的這些趨勢繼續發展,編譯型別可能是編寫 TypeScript 程式碼到執行之間的唯一步驟,我們不想成為阻礙良好開發體驗的人!

在某些方面,我們的 JavaScript 支援彌補了這一差距,如果您使用像Visual Studio或Visual Studio Code這樣的編輯器,可能已經見過 JSDoc 形式新增型別註釋:

/**
 * @param a {number}
 * @param b {number}
 */
function add(a, b) {
    return a + b;
}

因為這些只是註釋,它們根本不會改變程式碼的執行方式——它們只是一種文件形式,但TypeScript利用了它們,通過程式碼補全、自動重構等方式為您提供更好的JavaScript編輯體驗。甚至可以通過在檔案頂部新增 // @ts check 註釋來新增 型別檢查 [1] ,或者通過TypeScript編譯器,開啟 checkJs 選項來執行這些檔案。這個特性使得在不需要構建步驟的情況下就可以獲得一部分的TypeScript體驗,您可以將其用於小型的指令碼、基本網頁和 Node.js服務端程式碼等等。

不過,您會注意到這有點冗長,失去了 TypeScript 寫型別的簡潔性。

如果我們全都要呢?

如果我們可以有一些像TypeScript這樣的語法,但在JavaScript中完全被忽略——有點像註釋。

function add(a: number, b: number) {
    return a + b;
}

我們的團隊相信這裡有很大的潛力,本月我們希望將其 作為提案提交 [2] 給ECMAScript標準委員會TC39!

如何工作?

當我們被問到“JavaScript什麼時候能擁有型別?”,我們回答的很猶豫。在過去,如果你問開發人員他們對JavaScript中的型別有什麼想法,你會得到很多不同的答案。一些人認為型別應該被完全忽略,而另一些人則認為它們應該具有某種意義——可能是它們應該執行某種執行時驗證,或者它們應該作為引擎優化的提示等等。但在過去幾年裡,我們看到人們更傾向於一種與TypeScript的發展方向一致的設計,即型別在執行時被完全忽略且可擦除。現在我們可以自信的提出“型別作為註釋”的提案了。

這個提案的想法是 [3] ,可以開創一組語法,JavaScript 完全忽視它,但TypeScript、Flow等工具可以使用這些語法。這使我們能夠保留您喜歡的TypeScript裡的內容——它的型別檢查和編輯體驗,同時消除開發中需要的構建步驟。

因此,在編寫和執行程式碼時,工具鏈看起來會有些不同。

與此同時,編寫程式碼和型別檢查將保持不變。開發人員可以在支援TypeScript的編輯器中獲得即時型別檢查反饋,在命令列裡執行TypeScript,將TypeScript新增到CI任務中。最大的區別是,因為我們不需要構建步驟,所以我們將大大降低JavaScript開發人員的入門門檻,讓他們體驗型別和優秀工具的強大功能。

要實現這一點,JavaScript只需為變數和函式上的型別註釋、可選性修飾符( ? )等新增語法對於引數和類成員、型別宣告( interfacetype 別名)和型別斷言運算子( as! )——所有這些都不會影響周圍程式碼的執行方式。

同時也支援可見性修飾符(例如 publicprivateprotected );然而, enumnamespace 將引數屬性不在本提案的範圍內,因為它們具有可見的執行時行為。根據反饋,這些特性可以作為單獨的ECMAScript特性提出,但我們當前的目標是支援TypeScript的一些大子集,我們認為這可能是JavaScript的一個很有價值的補充。

通過這一突破,我們為型別檢查器提供了創新的空間。這確實意味著引擎會很順利地執行程式碼,但我們相信型別檢查器可以(也應該)是規範性的,並實施比執行時更嚴格的約束。結合起來,這就形成了一種型別語法,可以跨不同的檢查器進行定製,或者如果有人認為他們對TypeScript或任何其他型別檢查器不滿意,也可以刪除掉。

這不是什麼?

值得一提的是,這個提議 不是什麼

我們的團隊沒有提出把 TypeScript 的型別檢查器放到每個瀏覽器和JavaScript執行時中 —— 我們也沒有提出要在瀏覽器中放入的任何新的型別檢查器。我們認為這樣做會導致JavaScript和TypeScript使用者的一系列問題,例如執行時效能、相容性問題以及扼殺型別領域的創新。

相反,我們只是提出了與TypeScript相容並受其驅動的語法,任何型別檢查器都可以使用它,但JavaScript引擎會跳過它。我們相信這種方法對每個人來說都是最有前途的,並將繼續允許TypeScript、Flow和其他人繼續創新。

接下來?

鑑於所有這些,我們計劃在即將到來的2022年3月TC39全體會議上提交 Stage 1 [4] 的提案。我們將在這項提案的共同倡導者,彭博社的 Rob Palmer [5] 和Igalia的 Romulo Cintra [6] 的支援和指導下完成這項工作。

達到第1階段意味著標準委員會認為支援型別語法對於ECMAScript是值得考慮的。這並不是一件肯定會引起轟動的事情——委員會內部有許多有價值的觀點,我們確實期待一些懷疑的聲音。這樣的提案會得到大量反饋和適當的審查。這一過程可能涉及大量的設計變更,可能需要數年時間才能產生結果。

但如果我們完成了這一切,我們就有機會對JavaScript世界做出最有影響力的改進之一。我們對此感到興奮,希望你們也一樣。

如果您有興趣瞭解更多關於細節和當前方向的資訊, 請前往提案的倉庫 [7] 。我們期待著聽到你的想法!

最後,TypeScript團隊和champions group要感謝所有從事 現有技術 [8] 工作的人,以及那些伸出援助之手幫助進行評論的撰稿人,尤其是幫助推動這項工作的 Gil Tayar [9] 。我們非常感激能成為這樣一個充滿激情的社群的一部分!

參考資料

[1]

型別檢查: https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html

[2]

作為提案提交: https://github.com/giltayar/proposal-types-as-comments

[3]

這個提案的想法是: https://github.com/giltayar/proposal-types-as-comments

[4]

Stage 1: https://tc39.es/process-document/

[5]

Rob Palmer: https://github.com/robpalme

[6]

Romulo Cintra: https://github.com/romulocintra

[7]

請前往提案的倉庫: https://github.com/giltayar/proposal-types-as-comments/

[8]

現有技術: https://github.com/giltayar/proposal-types-as-comments#prior-art

[9]

Gil Tayar: https://github.com/giltayar/

因為微信公眾號修改規則,如果不標星或點在看,你可能會收不到我公眾號文章的推送,請大家將本 公眾號星標 ,看完文章後記得 點下贊 或者 在看 ,謝謝各位