跳到主要內容

Deno 中 TypeScript 的常見問題

我可以使用未針對 Deno 編寫的 TypeScript 嗎?

也許可以。我們很遺憾,這是最好的答案。由於許多原因,Deno 選擇使用完全限定的模組指定符。部分原因是因為它將 TypeScript 視為一級語言。此外,Deno 使用明確的模組解析,沒有任何魔法。這與瀏覽器本身運作的方式實際上相同,儘管它們並未顯然直接支援 TypeScript。如果 TypeScript 模組使用未考慮這些設計決策的匯入,它們可能無法在 Deno 下運作。

此外,在 Deno 的最新版本(從 1.5 開始),我們已開始使用 Rust 函式庫在特定情況下將 TypeScript 轉換為 JavaScript。因此,在 TypeScript 中的某些情況下需要類型資訊,因此 Deno 不支援這些情況。如果您將 tsc 作為獨立程式使用,可以使用 "isolatedModules" 設定,並將其設定為 true,以確保您的程式碼能由 Deno 妥善處理。

處理擴充功能和缺乏 Node.js 非標準解析邏輯的方法之一是使用 匯入對應,這將允許您指定裸指定符的「套件」,然後 Deno 就能解析並載入這些套件。

Deno 支援哪些 TypeScript 版本?

Deno 是使用特定版本的 TypeScript 建置的。若要找出此版本,請在命令列中輸入下列內容

> deno --version

將會列印 TypeScript 版本(以及 Deno 和 v8 的版本)。Deno 嘗試與 TypeScript 的一般版本保持最新,並在 Deno 的下一個修補程式或次要版本中提供這些版本。

Deno 使用的 TypeScript 版本發生重大變更,為什麼會中斷我的程式?

我們不認為 TypeScript 發行版的行為變更或重大變更會造成 Deno 的重大變更。TypeScript 是一種普遍成熟的語言,而 TypeScript 中的重大變更幾乎總是「好事」,讓程式碼更健全,而我們最好讓所有程式碼都保持健全。如果 TypeScript 版本有重大變更,而且不適合使用舊版 Deno 直到問題解決為止,那麼你應該可以使用 --no-check 完全略過類型檢查。

此外,你可以使用 @ts-ignore忽略你控制的程式碼中的特定錯誤。你也可以使用 匯入對應 來取代整個依賴項,適用於依賴項的依賴項未受維護或有某種重大變更的情況,而你希望在等候更新時略過此變更。

我如何撰寫同時適用於 Deno 和瀏覽器,但仍進行類型檢查的程式碼?

你可以使用命令列上的 --config 選項搭配組態檔案來執行此操作,並調整檔案中 "compilerOptions" 中的 "lib" 選項。如需更多資訊,請參閱 針對 Deno 和瀏覽器

為什麼你強迫我使用孤立模組?為什麼我無法在 Deno 中使用 const 列舉?為什麼我需要執行 export type?

自 Deno 1.5 起,我們將 isolatedModules 預設為 true,而在 Deno 1.6 中,我們移除了透過組態檔案將其設定回 false 的選項。isolatedModules 選項會強制 TypeScript 編譯器檢查並發出 TypeScript,就好像每個模組都是獨立的一樣。TypeScript 目前在語言中有一些 類型導向發射。雖然不允許類型導向發射進入語言是 TypeScript 的設計目標,但它還是發生了。這表示 TypeScript 編譯器需要了解程式碼中的可擦除類型,才能決定要發射什麼,當你嘗試在 JavaScript 上建立一個完全可擦除的類型系統時,這就會變成一個問題。

當人們開始在沒有 tsc 的情況下轉譯 TypeScript 時,這些類型導向的發射就成了問題,因為像 Babel 這樣的工具只會嘗試刪除類型,而不需要理解類型來引導發射。

因此,我們決定不讓每個使用者了解我們何時以及如何支援類型導向的發射,而是強制將 isolatedModules 選項設為 true 來停用它們。這表示即使我們使用 TypeScript 編譯器來發射程式碼,它也會遵循 Rust 為基礎的發射器所遵循的相同「規則」。

這表示某些語言功能不受支援。這些功能包括

  • 類型的重新匯出具有歧義性,需要知道來源模組是匯出執行時期程式碼還是僅匯出類型資訊。因此,建議您對僅匯入和匯出類型的部分使用 import typeexport type。這將有助於確保在發射程式碼時,所有類型都會被刪除。
  • 不支援 const enumconst enum 需要類型資訊來引導發射,因為 const enum 會寫成硬編碼值。特別是當 const enum 被匯出時,它們只會建構類型系統。
  • export =import = 是我們不支援的舊版 TypeScript 語法。
  • 只支援 declare namespace。執行時期 namespace 是我們不支援的舊版 TypeScript 語法。

為何不支援語言服務外掛程式或轉換器外掛程式?

tsc 支援語言服務外掛程式,但 Deno 不支援。Deno 並非總是使用內建的 TypeScript 編譯器來執行其功能,而加入對語言服務外掛程式的支援所帶來的複雜性並不可行。TypeScript 不支援發射器外掛程式,但有幾個社群專案將發射器外掛程式駭入 TypeScript。首先,我們不希望支援 TypeScript 不支援的功能,此外,我們並非總是使用 TypeScript 編譯器進行發射,這表示我們需要確保在所有模式中都支援它,而另一個發射器是用 Rust 編寫的,這表示 TypeScript 的任何發射器外掛程式都無法用於 Rust 發射器。

如何在 IDE 中結合 Deno 程式碼與非 Deno 程式碼?

Deno 語言伺服器支援「針對每個資源」的設定,用以啟用或停用 Deno。這也需要用戶端 IDE 支援此功能。對於 Visual Studio Code,官方的 Deno 擴充功能 支援 vscode 的 多根工作區 概念。這表示你只需要將資料夾加入工作區,並視需要在每個資料夾中設定 deno.enable 設定即可。

對於其他 IDE,用戶端擴充功能需要支援類似的 IDE 概念。