TypeScript 編碼
工作流程
-
導覽。 在撰寫程式碼前,先閱讀專案的真實來源:
package.json(type、engines、packageManager、exports、scripts、已安裝的主要版本)、鎖定檔、每個tsconfig*.json及其extends鏈、根目錄的工作區、框架、lint 與格式設定(pnpm-workspace.yaml、turbo.json、next.config.ts、biome.json、.oxlintrc.json),以及 CI 中的標準檢查指令。執行tsc --showConfig來解析extends鏈;它會省略保持預設值的選項,請從references/modules.md中閱讀這些預設值(TypeScript 6 和 7 變更了它們)。閱讀您正在修改的模組及其鄰近模組;重用它們的輔助函式、錯誤型別、schema 與模式。 完成條件: 您能說出套件管理器、TypeScript 主要版本、module與moduleResolution、strict以外的嚴格性旗標(noUncheckedIndexedAccess、exactOptionalPropertyTypes、erasableSyntaxOnly)、lint 與格式化工具鏈,以及專案的檢查指令。 -
建模型別。 在控制流程之前先設計資料,遵循型別。自進程外部輸入:閱讀
references/zod.md。變更套件的公開 API:閱讀references/api.md。 完成條件: 變更所依賴的每個不變量都已編碼在型別中,且每個跨越信任邊界的值在使用的都已由 schema 解析。 -
緊密迭代實作。 以小步驟進行,並在每一步後執行
tsc --noEmit(使用專案參考時為tsc -b)。閱讀完整的診斷資訊;其代碼(TS2742)是搜索references/modules.md與references/types.md中表格的關鍵字。對於依賴項的 API,請在node_modules/<pkg>/中閱讀其已安裝版本的.d.ts。錯誤修正:先撰寫回歸測試並觀察其變紅。 完成條件: 變更通過型別檢查且無新的診斷,且任何回歸測試在修正前變紅、修正後變綠。 -
驗證。 透過專案的套件管理器(
pnpm exec、npx、bunx)執行步驟 1 中的專案指令;否則,對於專案使用的工具鏈:tsc --noEmit # tsc -b 當 tsconfig.json 只列出 references biome ci # Biome oxfmt --check && oxlint --type-aware --deny-warnings # oxlint + oxfmt vitest run --typecheck # 或專案的測試執行器- 根目錄的
tsconfig.json若包含"files": []與references,會使tsc --noEmit不檢查任何內容;請使用tsc -b。在沒有根目錄 tsconfig 的工作區中,請透過任務執行器(turbo run check-types test)對每個套件執行檢查。 - 讓
tsc與每個 linter 保持循環:Biome 的型別推斷與 oxlint 的型別感知規則補充它,絕不取代它。 - 格式化失敗:應用格式化工具(
biome check --write、oxfmt)而不是手動編輯。 - 從根本原因修正診斷。當抑制是正確的時,將其範圍限定在一行並給出原因:
// biome-ignore lint/<group>/<rule>: 原因、// oxlint-disable-next-line <rule> -- 原因、// @ts-expect-error 原因。 - 若修改了 lint 或格式設定:請對照
references/lints.md檢查,然後在整個儲存庫上(而不僅僅是變更的檔案)執行 linter 與格式化工具。 - 若觸及已發布套件的公開 API:執行
references/api.md。 完成條件: 每個指令都退出代碼 0,您變更的行沒有警告,且每個新的抑制都附有原因。
- 根目錄的
-
審查自己的 diff。 重新閱讀完整的
git diff(若檔案是新的則使用git add -A && git diff --cached),而不是依靠記憶,對照規則以及 diff 所觸及的每個參考檔案的規則。 完成條件: 每個區塊都是任務所需的,console.log、debugger、.only與註解掉的程式碼都已移除,文件註解與行為相符,且每個適用的規則都適用於每個區塊。
審查他人的程式碼:執行步驟 1,在可行的情況下執行步驟 4 的指令,然後將步驟 5 應用於他們的 diff。將每個發現報告為 path:line、規則與修正方式。
規則
型別
- 用證據縮小型別:
typeof、instanceof、in、區分標誌檢查、型別謂詞或 schema 解析。any、非空斷言!與as T是被禁止的,在測試中也一樣;as const與satisfies則保留。當函式庫的型別有誤時,請在源頭透過模組擴充修復(references/types.md)。 - 讓非法狀態不可表達:使用帶有字面量
kind欄位的判別式聯合,而非boolean旗標加上可選欄位。為 ID、單位與經過驗證的值加上品牌標記:透過 schema(z.string().brand<"UserId">())或型別謂詞,絕不使用as。 - 解析,而非驗證:
JSON.parse、Response.json()、環境變數、儲存空間、URL 參數與postMessage資料在邊界處經 Zod schema 解析前均為unknown;將解析後的型別向內傳遞。 - 對你擁有的聯合型別進行窮舉 switch:以
default: x satisfies never; throw new Error(...)結尾,或使用當新增成員時無法編譯的Record<Union, V>查找表。 - 在
noUncheckedIndexedAccess下,索引訪問的結果為T | undefined:處理undefined(使用守衛、?? 預設值、for...of),而不是斷言其不存在。 - 匯出的函式宣告其回傳型別;區域變數保持推斷。
- 物件形狀使用
interface,使用extends而非&交集;聯合型別、映射型別與條件型別使用type。 - 對於函式不會變異的輸入,接受
readonly T[]與Readonly<T>。 - 使用字串字面量聯合或
as const物件,而非包含執行時期程式碼的enum與命名空間(在erasableSyntaxOnly下皆禁止)。
錯誤與非同步
- 呼叫端必須處理的預期失敗應回傳一個判別式結果;錯誤與不可恢復的狀態則擲出帶有
{ cause }的Error子類別。詳細資訊:references/errors.md。 - 每個 promise 都必須被 await、回傳或傳遞給一個會觀察其拒絕的處理器。
當前慣用寫法
訓練資料早於 TypeScript 6 與 7:TypeScript 7 是 Go 原生編譯器,strict 預設開啟,types 預設為 [],且 baseUrl、outFile、target: "ES5" 與 moduleResolution: "node10" 已被移除(references/modules.md)。當已安裝的版本允許時,偏好當前形式,包括透過 lib 層級使用標準函式庫 API。當參考文件與已安裝套件的 .d.ts 或 CHANGELOG 不一致時,以已安裝版本為準。
| 偏好 | 而非 | 自版本 |
|---|---|---|
const config = { ... } satisfies Config | const config: Config(會擴寬)、as Config | 4.9 |
function f<const T>(x: T) | 在每個呼叫點使用 as const | 5.0 |
搭配 verbatimModuleSyntax 使用 import type { T } | importsNotUsedAsValues(已移除) | 5.0 |
using / await using 搭配 [Symbol.dispose] | try / finally 清理 | 5.2, lib esnext |
import data from "./d.json" with { type: "json" } | assert { type: "json" }(自 6.0 起為錯誤) | 5.3 |
NoInfer<T> | T & {} 推斷阻擋器 | 5.4 |
推斷謂詞:xs.filter((x) => x !== undefined) | 手寫 (x): x is T => 守衛 | 5.5 |
文件與註解
- 匯出的項目應附
/** */文件說明合約:@throws標示擲出的錯誤、@deprecated標示替代項目、@example當用法從簽名不明顯時提供範例。
依賴項
- 重用
package.json中已列出的項目,並在平台能滿足需求時優先使用平台功能:fetch、structuredClone、crypto.randomUUID、AbortSignal.timeout、以node:為前綴的內建模組。 - 使用專案的套件管理器新增依賴,並將
@types/*固定在執行時期套件的主要版本(@types/node:固定在engines中最低的 Node 版本)。
參考文件
根據您目前所在的分支載入對應的文件:
references/types.md:泛型、條件與映射型別、型別謂詞、模組擴充、型別層級錯誤。references/errors.md:定義錯誤型別、結果聯合、cause、層級之間的錯誤邊界。references/async.md:promises、使用AbortSignal取消、並發、using、非同步迭代。references/modules.md:tsconfig.json、package.json、模組解析、ESM 與 CommonJS、TypeScript 6 與 7 遷移、設定錯誤。references/zod.md:解析不受信任的輸入、schemas、Zod 4 API。references/react.md:React 元件、hooks、React 19 API、React Compiler。references/nextjs.md:Next.js App Router、Server Components 與 Functions、"use cache"、路由型別。references/recharts.md:Recharts 圖表、型別化dataKey、自訂 tooltip 與形狀、圖表尺寸調整。references/lints.md:設定或修改 Biome、oxlint 或 oxfmt。references/testing.md:撰寫測試、型別測試、React 元件測試、mocks。references/perf.md:型別檢查緩慢、編輯器延遲、bundle 大小、測量的熱點路徑。references/api.md:設計或修改已發布套件的公開 API、exports、宣告檔、semver;將typescript作為函式庫匯入的工具。references/runtimes.md:在 Node、Bun 或 Deno 上直接執行.ts。references/monorepo.md:pnpm workspaces、Turborepo、彼此依賴的套件。references/jsdoc.md:使用checkJs檢查的.js檔案、JSDoc 型別、將 JavaScript 遷移至 TypeScript。