[TS] TypeScript Config File (tsconfig)
此篇為各筆記之整理,非原創內容,資料來源可見下方連結與文後參考資料。
TSC
$ npx tsc -b . # build
$ npx tsc -b . --clean # 移除掉打包後產生的檔案
$ npx tsc --showConfig > ts-config.txt # 檢視實際上被 TypeScript 處理的檔案(最終吃到的設定檔)
$ npx tsc --project tsconfig.json --diagnostics > ts-diagnostics.txt
如果專案中有多個 tsconfig
檔案,用 references
把對應的 configuration 組在一起,例如(同時有 tsconfig.node.json
和 tsconfig.app.json
,template-react-ts/tsconfig.json @ GitHub),則使用 tsc -b
來執行才會對每一個 tsconfig 的檔案來做檢查,如果只是執行 tsc
或 tsc --project tsconfig.json
,則可能不會檢查到所有檔案。
參考:
Configuration
- TSConfig Reference @ TypeScript
- The TSConfig Cheat Sheet | Total TypeScript @ Matt Pocock
- React with TypeScript: Best Practices @ SitePoint
- Troubleshooting Handbook: tsconfig.json @ react-typescript-cheatSheet
設定檔
建議可以參考 The TSConfig Cheat Sheet @ Total TypeScript 的設定
如果是用 VS Code 的話,滑鼠移上去 property 就會顯示每個設定的描述:
- compilerOptions
baseUrl
:設成"baseUrl": "./src"
則可以使用 absolute path 來載入模組
include
:如果使用 glob pattern 但沒有指定副檔名的話,預設只會使用有支援的副檔名(例如,.ts
、.tsx
和.d.ts
,如果allowJs
是true
的話,則會一併啟用.js
和.jsx
),這些指定的檔案會從tsconfig.json
所放置的位置作為相對目錄。exclude
:從已經被include
中的檔案中加以排除掉。extends
- 被繼承檔案的設定會先被載入,接著被該檔案內的設定加已覆蓋
- 所有在設定檔中的相對路徑,都會根據原設定檔的位置加以解析
file
,include
和exclude
的內容會覆蓋掉被繼承的檔案中所寫的- 唯一一個不會被繼承的屬性是
references
- 帶有相對路徑的屬性不會被繼承,而是會根據原設定檔中的相對路徑被解析
Type Checking 相關
建議打開下述的 flag:
- noImplicitAny
- noUncheckedIndexedAccess:可以避免取用到不存在的 object property。
- useUnknownInCatchVariables:讓 catch 中的 error 預設是
unknown
type。 - exactOptionalPropertyTypes:讓 TypeScript 可以明確區分在定義型別時 optional (
?
) 或undefined
的差異
Project 相關
incremental
:把上一次 compilation 的資訊紀錄並保存下來,有助於加快下次執行 type-check 或 emit 所需的時間(參考:Faster subsequent builds with the--incremental
flag)。
Module 相關
module
:指程式打包後使用的 module system,例如commonjs
、umd
、node16
、es2022
、...等。
module
主要指的是打包後使用的 module system,主要指和 module 有關的語法;另一個欄位 target
指的則是「程式語法」本身打包後要支援到的環境版本,例如,如果環境不支援 arrow function,則打包後會編譯成一般的 function 語法。
Debug 相關
除了在執行 tsc 時加上 --showConfig
外(即,npx tsx --showConfig
),也可以在 tsconfig.json
中使用下述設定來 debug
diagnostics
:顯示診斷報告,可以用來看 performance,例如,執行的時間、檢查了多少檔案、消耗的記憶體explainFiles
:顯示 TypeScript 處理了那些檔案,以及之所以被 TypeScript 檢查的原因extendedDiagnostics
:相較於diagnostics
更完整的報告generateCpuProfile
listEmittedFiles
:顯示有那些被 emit 出來的檔案listFiles
:顯示有哪些檔案會被 TypeScript 給 compile,可以用來確定檔案有沒有被 TS 處理到,如果希望進一步了解回什麼會被 TS 處理到的原因,則可以改用explainFiles
traceResolution
// tsconfig.json
/* Visit https://aka.ms/tsconfig.json to read more about this file */
{
"compilerOptions": {
/* Basic Options */
"target": "ES2018", // compile 後要支援到的 ECMAScript 版本
"module": "commonjs", // compile 後程式碼會用 commonjs 來處理模組的匯出匯入
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": false, // 是否允許匯入 js 檔,會影響到 include 時解析的副檔名是否包含(.js 和 .jsx)
"declaration": true,
// 如果沒設定會套用預設值(TS 自動判斷)
// 有「機會」導致 src 的資料夾也一起被 build 到 dist 資料夾中
// 例如 TS 自動把 rootDir 判斷為 { "rootDir": "." }
"rootDir": "src",
// 預設 tsc 會直接把編譯好的 js 檔放在與 ts 檔相同的路徑,但這樣檔案 會很散亂,因此全部放到 dist
"outDir": "dist",
/* Strict Type-Checking Options */
"strict": true,
/* Additional Checks */
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true, // 確保 switch case 都會有 break 或 return
/* Module Resolution Options */
"baseUrl": "./", // 匯入模組時,路徑可以使用從 baseUrl 開始,而不需要 ./../ 這種寫法
"paths": {
"@": ["src"] // 將 @ map 到 src
},
"esModuleInterop": false,
/* Source Map Options */
"sourceMap": true,
/* Advanced Options */
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true // 確保檔案的大小寫一致,避免某些作業系統對大小寫不敏感
},
"include": ["src/**/*.ts"], // compiler 要做用在哪些檔案上
"exclude": []
}
如何提升 TypeScript compile、type-check、和 emit 的效率
keywords: performance
檢視編譯效能
首先,要檢視效能可以使用 tsconfig.json
中的 diagnostics
或 extendedDiagnostics
(完整的資訊)的設定,如此會顯示 TypeScript compile 時所消耗的時間。
了解 TypeScript 處理了那些檔案
接著先看 TypeScript 實際處理了那些檔案:
- 可以使用
--showConfig
來檢視設定
npx tsc --showConfig > tsconfig.txt
- 或者在
tsconfig.json
中使用listFiles
或explainFiles
的 option 來檢視實際被 TypeScript 處理到的檔案
這時候也許可以看到一些不需要但被 TypeScript 處理的檔案,例如 storybook_release