概述
本文是對 https://github.com/Microsoft/TypeScript/issues/4789 的翻譯。后續文章譯者會持續跟進后續進展并給出自己的評論。
術語定義
此文章用到了不少專業術語,為了閱讀方便,羅列部分關鍵術語如下:
- 智能感知:指的是IDE代碼提示、重構等技術的底層架構支持
- 基于可執行程序的智能感知:譯者猜測應該指一種使用獨立運行程序(exe)來實現的智能感知系統。
- JavaScript 語言服務:一種微軟開發的基于可執行程序的智能感知,被應用于 Visual Studio中。
- TypeScript 語言服務:TypeScript的一個模塊,實現功能類似 JavaScript語言服務,依托于 TypeScript 類型系統,并不基于可執行程序。
- 庫定義文件:指的是 TypeScript Definition File,即 .d.ts 文件
通過 TypeScript 完善 JavaScript
這個方案概述了通過使用和擴展 TypeScript 的能力,從而提供完善的JavaScript開發體驗。
當前問題
-
JavaScript 智能感知在如今是一個大雜燴。不同的產品的體驗有很大區別,并且經常是不一致或者不準確的。比如:
基于可執行程序( Execution )的智能感知會在大量動態代碼中失效(比如代碼依賴于一個外部資源或者用戶交互),行為會在不同的硬件上不同(因為達到了可執行程序的超時限制),并且是不可預知的(有時候是否可以正常工作取決于看似無關的編輯)
靜態分析引擎會進行深度代碼分析,比如跟蹤調用地點和條件分支,這通常會消耗大量的資源(特別是大型代碼庫)并且需要大量的代碼去維護和適配各種在長尾的類庫和模塊中用到的 JavaScript 模式。
-
類型支持是 TypeScript 中很棒的特性,并且提供了準確且一致的智能感知。但是很多開發者想繼續直接編寫 JavaScript 代碼,或者不想在他們已經存在的 JavaScript 項目中 處理所有的 TypeScript 錯誤。因此:
一些最好的 JavaScript 類庫已經擁有了 TypeScript 庫定義文件。但這對 JavaScript 開發者來說是無法使用的。
即使他們想把項目移植到 TypeScript 上也有很大的挑戰。如果只是簡單的把 .js 文件改名為 .ts 文件,會遭遇很多 TypeScript語法錯誤。
類型在 JavaScript 中可以通過其他方式建模,比如 JSDoc注釋格式。但是 IDE 支持和現存類庫的建模方式是?參差不齊的。
-
當前版本的 Visual Studio 對 JavaScript 的支持很差,對開發來說并不是一流的體驗。
基于可執行程序的JavaScript 語言服務,基于分析引擎的 Node Tools for Visual Studio ,擁有一個靜態類型系統的 TypeScript 工具,當在這些項目類型中編寫代碼時,上述內容并沒有集成起來。
除了不能跨越上下文理解代碼之外,這會導致不同的編碼體驗,比如 ES6 語法支持,自動格式化,智能感知行為等等。這三種方式都彼此略有不同。(更不用說這在編寫新特性、修復BUG時需要在三種實現中帶來很多重復的工作量)
機會
如果 TypeScript語言服務可以增強 JavaScript 開發體驗的話:
TypeScript 生態系統中提供的大量庫定義是可以被利用的,可以為這些類庫提供豐富的智能感知。
許多基于可執行程序或者分析引擎的智能感知系統的挑戰可以被避免。(還是有一些會出現,下文會進一步概述)
通過在 JavaScript 中利用 TypeScript的類型定義, TypeScript 可以理解(在某種程度上)JavaScript代碼。
這提供了一種在一個項目中混合編寫 TypeScript 和 JavaScript 代碼的能力,并且可以在必要的情況下逐步遷移既有的 JavaScript 代碼。
TypeScript 將 ES6+ 結構(比如類,箭頭函數,模塊等等)編譯成 ES5代碼的能力可以應用到 JavaScript 中。(允許編寫 JavaScript ES6代碼并運行在 ES5的引擎中)。這也適合于其他的 TypeScript特性(比如提供了通過 TypeScript TSX來提供對 JSX 的支持)
不同項目類型的代碼可以共享上下文(比如支持 ES5的瀏覽器中的代碼可以理解使用ES6編寫的Node模塊,并且都可以利用 TypeScript 接口定義)。
編碼體驗和設置是一致的(以 Visual Studio 為例,不再需要付出維護三套實現的工程成本,取而代之的是只改善其中一個)。
基于當前 TypeScript代碼庫可以讓 JavaScript開發體驗脫離出 VisualStudio。( TypeScript語言服務可以被非常簡單的應用在其他地方,比如 Sublime 插件,VS Code編輯器等)
挑戰
如何在 JavaScript 內聲明和使用類型(比如 JSDoc,lib.d.ts , node.d.ts ,第三方庫定義,定制代碼,類型推論,等等)
如何支持一些在 TypeScript 中現在不支持的通用 JavaScript 模式。(比如 RequireJS和 CommonJS 模塊,構造函數和原型屬性等等)
如何將 JavaScript 提供給 TypeScript 編譯過程中(比如那些文件需要被選取,編譯器參數等)
假設上述問題可以解決,由此產生的 JavaScript 開發者體驗( 比如讓 TypeScript 對只對JavaScript感興趣的開發者透明,當類型推斷失敗時候的智能感知體驗,對不同的項目類型設置不同的示例項目結構和設置,如何混合代碼或者集成到現有代碼中。
上述挑戰會在下面的內容中單獨的提及到。
JavaScript types in TypeScript
JavaScript module systems in TypeScript
JavaScript in TypeScript compilations
JavaScript developer experience