TypeScript 設定檔詳解 (tsconfig.json)
tsconfig.json 是 TypeScript 專案的設定檔,用來指定編譯選項和專案結構。這篇文章會詳細介紹常用的設定選項。
建立設定檔
使用 TypeScript 編譯器建立預設設定檔:
tsc --init
這會產生一個包含註解說明的 tsconfig.json 檔案。
基本結構
{
"compilerOptions": {
// 編譯選項
},
"include": [
// 要編譯的檔案
],
"exclude": [
// 要排除的檔案
],
"files": [
// 明確指定的檔案
]
}
檔案包含設定
include
指定要包含的檔案或目錄:
{
"include": ["src/**/*", "types/**/*"]
}
支援 glob 模式:
*:匹配任意字元(不包含目錄分隔符)**:匹配任意深度的目錄?:匹配單一字元
exclude
排除不需要編譯的檔案:
{
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}
預設會排除 node_modules、bower_components、jspm_packages 和 outDir。
files
明確指定要編譯的檔案(不支援 glob):
{
"files": ["src/index.ts", "src/utils.ts"]
}
編譯目標設定
target
指定編譯後的 JavaScript 版本:
{
"compilerOptions": {
"target": "ES2020"
}
}
常見值:
ES5:較舊的瀏覽器相容ES6/ES2015:支援 class、arrow function 等ES2020:支援 optional chaining、nullish coalescingESNext:最新的 ECMAScript 版本
module
指定模組系統:
{
"compilerOptions": {
"module": "ESNext"
}
}
常見值:
CommonJS:Node.js 預設ES6/ES2015/ES2020:ES 模組ESNext:最新的模組系統AMD、UMD、System:其他模組系統
lib
指定要包含的內建型別定義:
{
"compilerOptions": {
"lib": ["ES2020", "DOM", "DOM.Iterable"]
}
}
常見值:
ES5、ES6、ES2020等:JavaScript 內建型別DOM:瀏覽器 DOM APIWebWorker:Web Worker API
輸出設定
outDir
指定編譯後檔案的輸出目錄:
{
"compilerOptions": {
"outDir": "./dist"
}
}
rootDir
指定原始碼的根目錄:
{
"compilerOptions": {
"rootDir": "./src"
}
}
outFile
將所有輸出合併為單一檔案(僅限 AMD 或 System 模組):
{
"compilerOptions": {
"outFile": "./dist/bundle.js"
}
}
declaration
產生 .d.ts 型別宣告檔案:
{
"compilerOptions": {
"declaration": true,
"declarationDir": "./dist/types"
}
}
sourceMap
產生 source map 檔案,方便除錯:
{
"compilerOptions": {
"sourceMap": true
}
}
嚴格模式設定
strict
啟用所有嚴格檢查:
{
"compilerOptions": {
"strict": true
}
}
這等同於啟用以下所有選項:
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true
}
}
noImplicitAny
禁止隱式 any 型別:
// noImplicitAny: true
function greet(name) {
// 錯誤:參數 'name' 隱式具有 'any' 型別
console.log(name);
}
// 需要明確標註型別
function greet(name: string) {
console.log(name);
}
strictNullChecks
嚴格的 null 和 undefined 檢查:
// strictNullChecks: true
let name: string = null; // 錯誤
let name: string | null = null; // OK
noImplicitReturns
確保函式所有路徑都有回傳值:
// noImplicitReturns: true
function getValue(condition: boolean): number {
if (condition) {
return 1;
}
// 錯誤:不是所有程式碼路徑都回傳值
}
noUnusedLocals
檢查未使用的區域變數:
// noUnusedLocals: true
function example() {
const unused = 'hello'; // 錯誤:'unused' 已宣告但從未使用
}
noUnusedParameters
檢查未使用的函式參數:
// noUnusedParameters: true
function greet(name: string, unused: number) {
// 錯誤:'unused' 未使用
console.log(name);
}
// 使用 _ 前綴可以忽略
function greet(name: string, _unused: number) {
console.log(name);
}
模組解析設定
moduleResolution
指定模組解析策略:
{
"compilerOptions": {
"moduleResolution": "node"
}
}
值:
node:Node.js 風格解析bundler:適用於打包工具(TypeScript 5.0+)classic:舊版 TypeScript 解析
baseUrl
設定模組解析的基礎路徑:
{
"compilerOptions": {
"baseUrl": "./src"
}
}
paths
設定路徑別名:
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@/*": ["./*"],
"@components/*": ["./components/*"],
"@utils/*": ["./utils/*"]
}
}
}
使用:
import { Button } from '@components/Button';
import { formatDate } from '@utils/date';
typeRoots
指定型別定義的搜尋目錄:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"]
}
}
types
只包含指定的型別套件:
{
"compilerOptions": {
"types": ["node", "jest"]
}
}
JavaScript 互通設定
allowJs
允許編譯 JavaScript 檔案:
{
"compilerOptions": {
"allowJs": true
}
}
checkJs
對 JavaScript 檔案進行型別檢查:
{
"compilerOptions": {
"checkJs": true
}
}
esModuleInterop
啟用 ES 模組和 CommonJS 的互通:
{
"compilerOptions": {
"esModuleInterop": true
}
}
這允許:
// 可以使用預設匯入 CommonJS 模組
import express from 'express';
// 而不是
import * as express from 'express';
allowSyntheticDefaultImports
允許從沒有預設匯出的模組使用預設匯入:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true
}
}
JSX 設定
jsx
指定 JSX 的編譯方式:
{
"compilerOptions": {
"jsx": "react-jsx"
}
}
值:
preserve:保留 JSX,由其他工具處理react:轉換為React.createElementreact-jsx:轉換為_jsx(React 17+)react-native:保留 JSX
其他常用設定
skipLibCheck
跳過型別宣告檔案的檢查:
{
"compilerOptions": {
"skipLibCheck": true
}
}
可以加快編譯速度,但可能忽略某些型別錯誤。
forceConsistentCasingInFileNames
強制檔案名稱大小寫一致:
{
"compilerOptions": {
"forceConsistentCasingInFileNames": true
}
}
resolveJsonModule
允許匯入 JSON 檔案:
{
"compilerOptions": {
"resolveJsonModule": true
}
}
isolatedModules
確保每個檔案可以獨立編譯:
{
"compilerOptions": {
"isolatedModules": true
}
}
這在使用 Babel 或其他轉譯器時很重要。
常見設定範例
React 專案
{
"compilerOptions": {
"target": "ES2020",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Node.js 專案
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
函式庫專案
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
繼承設定
使用 extends 繼承其他設定檔:
// tsconfig.base.json
{
"compilerOptions": {
"strict": true,
"esModuleInterop": true
}
}
// tsconfig.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["src"]
}
專案參考 (Project References)
用於大型 monorepo 專案:
// tsconfig.json
{
"references": [
{ "path": "./packages/common" },
{ "path": "./packages/frontend" },
{ "path": "./packages/backend" }
]
}