TypeScript 與 tsconfig.json

TypeScript 與 tsconfig.json

本文將說明 TypeScript 與 tsconfig.json。

從 TypeScript 的基本作用開始,將透過具體範例說明 tsconfig.json 在專案中的運作方式。

YouTube Video

TypeScript 與 tsconfig.json

TypeScript 是「帶有型別的 JavaScript」。然而,若要在實際專案中有效利用 TypeScript,正確理解並有意識地設定 tsconfig.json是不可或缺的。

為什麼我們需要 TypeScript?

首先,使用 TypeScript 最大的原因是**「可以在執行之前發現錯誤」**。

1function add(a: number, b: number): number {
2  return a + b;
3}
4
5add(1, "2");

這段程式碼在 JavaScript 中直到執行階段才會出錯,但在 TypeScript 中會在編譯階段就產生型別錯誤

這種「及早發現」大幅提升了開發效率與品質。

TypeScript 要如何執行?

原則上,TypeScript 不能直接執行。必須使用 tsc(TypeScript 編譯器)將其轉換為 JavaScript 才能執行。

1npm install -D typescript
2npx tsc --init
  • 執行這個操作後會產生 tsconfig.json,做為定義 TypeScript 專案行為的核心設定檔

tsconfig.json 的作用是什麼?

tsconfig.json 是用來決定**「要處理哪些檔案」、「依據哪些規則」以及「如何轉換」**的設定檔。雖然一開始看起來很複雜,但其實真正重要的設定只有幾項。

1{
2  "compilerOptions": {
3    "target": "ES2020",
4    "module": "ESNext",
5    "strict": true
6  }
7}
  • 只要這些設定就能進行現代且安全的 TypeScript 開發

target:指定輸出的 JavaScript 版本

target 用來決定輸出 JavaScript 的規格版本

1"target": "ES2020"

這樣設定後,TypeScript 將輸出相當於 ES2020 的 JavaScript。如需支援舊環境可選擇 ES5,只支援最新環境則可以選擇 ES2022 等。

指定 ESNext 時

1"target": "ESNext"
  • ESNext 表示將當前可用的最新 JavaScript 語法原樣輸出。TypeScript 不會轉譯這些語法,而是交由 Node.js 或瀏覽器等執行環境來處理。

  • 所以,ESNext 適合僅支援最新 Node.js 或使用 Babel、bundler 另外轉譯的情境。相反地,若執行環境不支援最新語法,則可能會造成執行時錯誤,因此需特別注意。

module:指定模組格式

module 用來指定模組格式

1"module": "ESNext"
  • ESNext 在前端與現代 Node.js 環境中已成為標準。
  • 只有需要 CommonJS 時才選擇 "CommonJS"

strict:最大化型別安全性

strict最大化 TypeScript 安全性的開關

1"strict": true
  • 啟用後能徹底檢查模糊型別與潛在錯誤。

strict 模式與隱含 any

當啟用 strict 時,TypeScript 會將無法推斷型別的變數視為錯誤

1function printValue(value) {
2	console.log(value);
3}
  • 此變數 value 宣告時沒有型別資訊,因此 TypeScript 無法判斷其型別。因此會隱含為 any,在 strict 模式下會觸發警告(錯誤)。
1function printValue(value: number) {
2	console.log(value);
3}
  • 如上述明確指定型別,TypeScript 就能判斷「這個變數只處理數字」。在 TypeScript 中,能夠唯一判斷型別省略型別更為重要。

include/exclude:控制要編譯的檔案範圍

tsconfig.json 中,可以明確指定要包含要排除哪些檔案進行編譯。

1{
2  "include": ["src"],
3  "exclude": ["node_modules"]
4}
  • 這樣設定後,只有 src 底下的檔案會被 TypeScript 管理。
  • exclude 指定的 node_modules 即使在 include 下,也會被排除編譯。

outDir:指定輸出目錄

設定 outDir 就能指定編譯輸出的檔案資料夾。

1"outDir": "dist"
  • 這樣一來,所有編譯後的檔案都會輸出到 dist 資料夾。實務上,分離原始碼與編譯產物是標準做法。

rootDir:指定原始碼目錄

rootDir 是用來指定TypeScript 所認定的原始碼根目錄

1"rootDir": "src"
  • 這個設定讓 TypeScript 在輸出時能保留以 src 為基準的目錄結構。 例如,src/index.ts 會輸出成 dist/index.js

  • rootDir 指定的目錄結構會在 outDir 裡被保留。

esModuleInterop:連接 CommonJS 與 ES 模組

接下來介紹 esModuleInterop

1"esModuleInterop": true
  • 啟用後,可用 import 語法安全地引用 CommonJS 模組。
1import fs from "fs";
  • 此設定在使用 Node.js 時幾乎是必須的

noImplicitAny:禁止隱含 any 型別

tsconfig.json 中強化型別檢查也非常重要。

1"noImplicitAny": true
  • 這樣設定後可禁止隱含 any 型別。可確實檢查出遗漏指定型別的部分。

檢查未使用程式碼的設定

檢查未使用程式碼的設定,有助於維護性提升。

1"noUnusedLocals": true,
2"noUnusedParameters": true
  • 設定後,未使用的變數或參數可即時收到警告。

lib:定義可用的內建 API

lib 是用來指定TypeScript 假設存在的標準 API的設定。

1"lib": ["ES2020", "DOM"]
  • 設置後,可使用以下類型:。 設為 ES2020 即可用 PromiseMapSet 等現代功能。 設為 DOM,則能使用 documentwindowHTMLElement 等瀏覽器 API。

前端專案加上 DOM;純 Node.js 專案則移除 DOM避免多餘的全域型別被引入

moduleResolution:模組查找規則

moduleResolution 決定import 語句中的模組如何被解析

1"moduleResolution": "Node"

主要有以下兩種選項:。

  • 指定 Node 時,會使用 Node.js 的模組解析規則。
  • Classic 是舊版 TypeScript 特有方法,現今很少使用。

在 Node.js 或使用 bundler 的環境中,明確指定 Node 是最保險的做法

最精簡且可用於正式環境的 tsconfig.json

根據上述內容,最精簡可用於正式環境的 tsconfig.json 範例如下:。

 1{
 2  "compilerOptions": {
 3    "target": "ES2020",
 4    "module": "ESNext",
 5    "moduleResolution": "Node",
 6    "lib": ["ES2020", "DOM"],
 7    "strict": true,
 8    "rootDir": "src",
 9    "outDir": "dist",
10    "esModuleInterop": true,
11    "noImplicitAny": true,
12    "noUnusedLocals": true,
13    "noUnusedParameters": true
14  },
15  "include": ["src"]
16}

這份設定能為前端與 Node.js 專案提供安全的基礎。

總結:tsconfig.json 就是「規則手冊」

tsconfig.json 不只是設定檔,更是對全專案適用的「規則手冊」。透過 tsconfig.json,下列重要原則能被明確定義:。

  • 型別安全等級。
  • 團隊的程式撰寫慣例。
  • 預防未來的錯誤。

理解 tsconfig.json,你將能不只撰寫 TypeScript,更能設計專案以安全地使用 TypeScript

您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。

YouTube Video