跳至主要內容

在 Deno 中設定 TypeScript

TypeScript 附帶許多可供設定的不同選項,但 Deno 致力於讓 TypeScript 易於與 Deno 搭配使用。許多不同的選項會妨礙此目標。為了簡化作業,Deno 會將 TypeScript 設定為「立即運作」,且不應需要其他設定。

話雖如此,Deno 確實支援使用 TypeScript 設定檔。若要搭配 Deno 使用 TypeScript 設定檔,您可以在命令列上提供路徑,或使用預設值。例如

> deno run --config ./deno.json main.ts

⚠️ 但請考慮,如果您建立需要設定檔的函式庫,若您將模組以 TypeScript 形式散佈,所有模組的使用者也將需要該設定檔。此外,您在設定檔中執行的設定可能會讓其他 TypeScript 模組不相容。老實說,最好使用 Deno 預設值,並仔細考慮是否要使用設定檔。

⚠️ Deno v1.14 開始支援更通用的設定檔,不再侷限於指定 TypeScript 編譯器設定。使用 tsconfig.json 作為檔名仍然可行,但我們建議使用 deno.jsondeno.jsonc,因為我們計畫在未來的版本中自動查詢此檔。

Deno 如何使用設定檔

Deno 不會像 tsc 那樣處理 TypeScript 設定檔,因為 TypeScript 設定檔的許多部分在 Deno 環境中沒有意義,或者如果套用這些部分,Deno 將無法正常運作。

Deno 只會查看設定檔的 compilerOptions 區段,即使如此,它也只會考慮某些編譯器選項,而忽略其他選項。

以下是可變更的編譯器選項表格,它們在 Deno 中的預設值以及關於該選項的其他說明

選項預設值說明
allowJstrue這幾乎不需要變更
allowUnreachableCodefalse
allowUnusedLabelsfalse
checkJsfalse如果 true 會導致 TypeScript 檢查 JavaScript 類型
jsx"react"
jsxFactory"React.createElement"
jsxFragmentFactory"React.Fragment"
keyofStringsOnlyfalse
lib[ "deno.window" ]此預設值會根據 Deno 中的其他設定而有所不同。如果提供此值,它會覆寫預設值。請參閱下方以取得更多資訊。
noErrorTruncationfalse
noFallthroughCasesInSwitchfalse
noImplicitAnytrue
noImplicitReturnsfalse
noImplicitThistrue
noImplicitUseStricttrue
noStrictGenericChecksfalse
noUnusedLocalsfalse
noUnusedParametersfalse
noUncheckedIndexedAccessfalse
reactNamespaceReact
stricttrue
strictBindCallApplytrue
strictFunctionTypestrue
strictPropertyInitializationtrue
strictNullCheckstrue
suppressExcessPropertyErrorsfalse
suppressImplicitAnyIndexErrorsfalse
useUnknownInCatchVariablesfalse

如需編譯器選項完整清單以及它們如何影響 TypeScript,請參閱 TypeScript 手冊

隱含 tsconfig.json 的外觀

不可能讓 tsc 的行為像 Deno。讓 TypeScript 語言服務的行為像 Deno 也很困難。這就是我們直接在 Deno 中建置語言服務的原因。話雖如此,了解隱含的內容還是有幫助的。

如果您要為 Deno 編寫 tsconfig.json,它看起來會像這樣

{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"experimentalDecorators": false,
"inlineSourceMap": true,
"isolatedModules": true,
"jsx": "react",
"lib": ["deno.window"],
"module": "esnext",
"moduleDetection": "force",
"strict": true,
"target": "esnext",
"useDefineForClassFields": true
}
}

您無法將此複製貼上到設定檔中並讓它運作,特別是因為 TypeScript 編譯器提供的內建類型函式庫是 Deno 的自訂類型函式庫。這可以使用命令列上的 deno types 來模擬,並將輸出導向到檔案中,並將其包含在檔案中作為程式的一部分,移除 "lib" 選項,並將 "noLib" 選項設定為 true

如果您使用 --unstable 旗標,Deno 會將 "lib" 選項變更為 [ "deno.window", "deno.unstable" ]。如果您嘗試載入工作執行緒,它會使用 "deno.worker" 進行類型檢查,而不是 "deno.window"。請參閱 類型檢查 Web 工作執行緒 以取得更多相關資訊。

使用「lib」屬性

Deno 有幾個內建函式庫,在其他平台(例如 tsc)中沒有。這讓 Deno 能夠正確檢查為 Deno 編寫的程式碼。不過,在某些情況下,這種自動行為可能會造成挑戰,例如撰寫也打算在瀏覽器中執行的程式碼。在這些情況下,compilerOptions"lib" 屬性可用於修改 Deno 在類型檢查程式碼時的行為。

內建函式庫對使用者來說很重要

  • "deno.ns" - 此包含所有自訂 Deno 全域命名空間 API,以及 import.meta 中的 Deno 新增功能。這通常不會與其他函式庫或全域類型衝突。
  • "deno.unstable" - 此包含新增的不穩定 Deno 全域命名空間 API。
  • "deno.window" - 這是檢查 Deno 主執行時期腳本時使用的「預設」函式庫。它包含 "deno.ns",以及 Deno 內建擴充功能的其他類型函式庫。此函式庫會與 "dom""dom.iterable" 等標準 TypeScript 函式庫衝突。
  • "deno.worker" - 這是檢查 Deno 網路工作執行緒腳本時使用的函式庫。如需有關網路工作執行緒的更多資訊,請查看 類型檢查網路工作執行緒
  • "dom.asynciterable" - TypeScript 目前不包含 Deno(以及多個瀏覽器)實作的 DOM 非同步可迭代項目,因此我們在 TypeScript 中提供此實作,直到它可用為止。

這些是 Deno 未使用的常見函式庫,但在撰寫同時適用於其他執行時期的程式碼時很有用

  • "dom" - TypeScript 附帶的主要瀏覽器全域函式庫。類型定義在許多方面與 "deno.window" 衝突,因此如果使用 "dom",請考慮僅使用 "deno.ns" 來公開 Deno 特定 API。
  • "dom.iterable" - 瀏覽器全域函式庫的可迭代擴充功能。
  • "scripthost" - Microsoft Windows Script Host 的函式庫。
  • "webworker" - 瀏覽器中網路工作執行緒的主要函式庫。與 "dom" 類似,這會與 "deno.window""deno.worker" 衝突,因此請考慮僅使用 "deno.ns" 來公開 Deno 特定 API。
  • "webworker.importscripts" - 在網路工作執行緒中公開 importScripts() API 的函式庫。
  • "webworker.iterable" - 將可迭代項目新增到網路工作執行緒中物件的函式庫。現代瀏覽器支援此功能。

鎖定 Deno 和瀏覽器

常見的用例是撰寫可在 Deno 和瀏覽器中運作的程式碼:使用條件檢查來判斷程式碼執行的環境,然後再使用特定於其中一者的任何 API。如果是這種情況,compilerOptions 的常見組態會如下所示

{
"compilerOptions": {
"target": "esnext",
"lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
}
}

這應允許 Deno 正確類型檢查大部分程式碼。

如果您預期使用 --unstable 旗標在 Deno 中執行程式碼,那麼您也會想要將該函式庫新增到組合中

{
"compilerOptions": {
"target": "esnext",
"lib": [
"dom",
"dom.iterable",
"dom.asynciterable",
"deno.ns",
"deno.unstable"
]
}
}

通常,當您在 TypeScript 中使用 "lib" 選項時,您也需要包含「es」函式庫。在 "deno.ns""deno.unstable" 的情況下,當您將它們引入時,它們會自動包含 "esnext"

執行類似操作時最大的「危險」在於類型檢查明顯較為寬鬆,而且無法驗證您是否在程式碼中執行足夠且有效的特徵偵測,這可能會導致原本微不足道的錯誤變成執行時期錯誤。

使用「types」屬性

"compilerOptions" 中的 "types" 屬性可用於指定在類型檢查程式時要包含的任意類型定義。如需更多相關資訊,請參閱 使用環境或全域類型