【実務・中級編】 tsconfig.jsonのextends機能 – TypeScript実践ガイド

なぜ、あなたの `tsconfig.json` は「肥大化」するのか?― `extends` で実現する秩序あるアーキテクチャ

現場でコードを書いていて、こんな経験はないだろうか。
「テスト環境だけ `skipLibCheck` を変えたい」「ビルド用の設定と開発用の設定を分けたい」。そのたびに巨大な `tsconfig.json` をコピー&ペーストして、微妙に異なる設定を管理し、いつの間にかどの設定が正解なのか誰にも分からなくなっている……。

それ、`tsconfig.json` の `extends` 機能を使っていないのが原因だ。

フロントエンドの現場では、コードのDRY原則を徹底するのと同じくらい、「設定のDRY原則」が重要になる。今日は、保守性を爆上げする賢い設定の継承術を叩き込む。

—

ブラウザやランタイムは `tsconfig.json` を見ていないという現実

まず前提として、TypeScriptのコンパイラ(`tsc`)や `ts-node`、あるいは `esbuild` や `Vite` のトランスパイルプロセスは、コンパイル時にこの設定ファイルを読み込む。しかし、ブラウザが直接これを読み込むことはない。

設定ファイルはあくまで「開発者の意図」をコンパイラに伝えるための指示書だ。この指示書が複雑怪奇になると、開発環境の再現性が下がり、チーム開発では「俺の環境では動くのに!」という呪いの言葉が飛び交うことになる。

`extends` を使えば、「ベースライン(共通の型定義・ルール)」と「特定のコンテキスト(テスト、ビルド、検証)」を分離できる。これがスケーラブルなプロジェクトの第一歩だ。

—

実践!美しい `tsconfig` の階層構造

現場で推奨されるのは、以下のような3層構造だ。

1. `tsconfig.base.json`: プロジェクト全体の厳格なルール(`strict: true` など)。
2. `tsconfig.json`: アプリケーションのメイン設定。
3. `tsconfig.test.json`: テストコード用の設定(`jest` の型定義追加など)。

1. ベース設定 (tsconfig.base.json)

まずは一番の親玉を作る。ここは「TypeScriptとしてのあるべき姿」を定義する場所だ。

{
“compilerOptions”: {
“target”: “ESNext”,
“module”: “ESNext”,
“strict”: true, // これをオフにするチームには未来がない
“esModuleInterop”: true,
“skipLibCheck”: true, // node_modulesの型チェックをスキップして爆速化
“forceConsistentCasingInFileNames”: true,
“moduleResolution”: “node”
}
}

2. アプリケーション設定 (tsconfig.json)

次に、ベースを継承しつつ、フロントエンド特有の設定を注入する。

{
“extends”: “./tsconfig.base.json”,
“compilerOptions”: {
“jsx”: “react-jsx”, // React環境なら必須
“baseUrl”: “.”,
“paths”: {
“@/”: [“src/”] // パスエイリアスでインポートを綺麗に
}
},
“include”: [“src”]
}

3. テスト設定 (tsconfig.test.json)

最後に、`jest` や `vitest` を使うときの設定。テストコードは本番用コードとはルールが少し違う(例えば `node` の型定義が必要など)。

{
“extends”: “./tsconfig.json”, // アプリ設定を継承
“compilerOptions”: {
“types”: [“jest”, “node”] // テスト用ライブラリの型を追加
},
“include”: [“src//.test.ts”, “jest.setup.ts”]
}

—

ここがプロの勘所:`extends` を使う際の注意点

`extends` を使うとき、若手がよくハマる落とし穴がある。

  • `files`, `include`, `exclude` は上書きされる:

`compilerOptions` はマージされるが、`include` などのファイル指定系は、子側で書くと親の設定を完全に上書きしてしまう。だからこそ、ベース設定にはあえて `include` を書かず、各環境ごとの設定で指定するのが安全だ。

  • パスの解決を意識する:

`extends` に指定するパスは、現在のファイルからの相対パスだ。階層が深くなると迷子になりやすいので、できるだけルート階層に設定ファイルを置く構成を維持しよう。

  • 「何でも継承」は悪:

あまりに細かく継承しすぎると、今度は「どこで設定が上書きされているのか」を追うのが困難になる。3階層程度が、読みやすさと柔軟性のスイートスポットだ。

まとめ:設定を「コード」として愛せ

`tsconfig.json` は単なる設定ファイルではなく、「チームの規律」そのものだ。

設定をDRYに保つことは、後からジョインするエンジニアが「このプロジェクトのルールは何なのか?」を一目で理解できるようにすることに直結する。複雑な設定をコピペで散らかすのは今日で終わりにしよう。

まずは今すぐ、プロジェクト内のバラバラな `tsconfig` を見つけ出して、共通部分を `tsconfig.base.json` に切り出してみてほしい。その瞬間、君のプロジェクトは少しだけ「モダン」で「頼もしい」ものに進化するはずだ。

何か詰まったら、いつでも聞いてくれ。アーキテクチャの泥沼から引き上げてやるよ。

コメント

タイトルとURLをコピーしました