TypeScript 設定檔 (tsconfig.json)

tsconfig.json 是 TypeScript 專案的靈魂。它告訴編譯器:「我的檔案在哪裡?我要編譯成什麼版本的 JS?這有多嚴格?」

快速產生

在專案根目錄執行:

tsc --init

這會產生一個充滿註解的 tsconfig.json

關鍵選項詳解

雖然選項有一百多個,但真正重要的只有這幾個:

1. compilerOptions (編譯核心設定)

這是在設定編譯器的行為。

{
  "compilerOptions": {
    /* 基礎設定 */
    "target": "es2016", // 編譯出來的 JS 版本。建議設為 "es2016" 或更新
    "module": "commonjs", // 模組系統。Node.js 用 "commonjs",前端專案通常用 "esnext"
    "rootDir": "./src", // 原始碼在哪裡?
    "outDir": "./dist", // 編譯後的檔案要放哪裡?

    /* 嚴格模式 (一定要開!) */
    "strict": true, // 開啟所有最嚴格的檢查。這包含 noImplicitAny, strictNullChecks 等等

    /* 模組解析 */
    "esModuleInterop": true, // 讓你方便匯入 CommonJS 模組 (例如 import React from "react")
    "skipLibCheck": true, // 跳過 node_modules 裡的型別檢查 (加快編譯速度)
    "forceConsistentCasingInFileNames": true // 確保檔案名稱大小寫一致 (Windows/Mac 跨平台很重要)
  }
}

2. include & exclude

告訴 TS 哪些檔案要處理,哪些不要。

{
  "include": ["src/**/*"], // 只要編譯 src 下的所有檔案
  "exclude": ["node_modules", "**/*.test.ts"] // 不要編譯這些
}

strict: true 到底做了什麼?

這是最重要的一個開關,它其實是以下幾個開關的總和:

  1. noImplicitAny: 不允許變數有「隱式」的 any (一定要明確寫出型別)。
  2. strictNullChecks: nullundefined 是獨立的型別,不能隨便塞給 stringnumber
  3. strictFunctionTypes: 更嚴格的檢查函式參數是否相容。
  4. strictBindCallApply: 檢查 .call, .bind, .apply 的參數正確性。
  5. strictPropertyInitialization:確保 class 的屬性都有被初始化。
  6. noImplicitThis: 不允許 this 的型別不明確。
  7. useUnknownInCatchVariables: catch(err) 裡的 err 預設是用 unknown 而不是 any

強烈建議:永遠開啟 strict: true。雖然剛開始會報很多錯,但它能幫你擋下無數的潛在 bug。

常見情境設定範例

1. Node.js 後端專案

{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

2. React / Vue 前端專案

通常前端專案會搭配 Webpack 或 Vite,這些打包工具會負責處理模組,所以設定會有些不同。

{
  "compilerOptions": {
    "target": "esnext", // 交給打包工具轉譯
    "module": "esnext", // 使用 ES Modules
    "moduleResolution": "node",
    "jsx": "react-jsx", // 支援 React JSX
    "strict": true
  }
}