【実務・中級編】 extendsプロパティによる設定の継承と階層化 – TypeScript実践ガイド

現場で戦うエンジニアの皆さん、お疲れ様です。

TypeScriptのプロジェクトが大きくなればなるほど、`tsconfig.json` の管理は「巨大な1枚岩」になりがちです。気づけば数百行に膨れ上がり、誰も触りたくない「神ファイル」としてレポジトリの肥やしになっている……なんて光景、よく見かけますよね。

今日は、そんなカオスを整理し、大規模開発でも通用する「tsconfigの階層化戦略」について、現場の知見を交えて語ろうと思います。

—

1. なぜ「継承(extends)」が必要なのか

まず大前提ですが、TypeScriptのコンパイラ(`tsc`)にとって、`tsconfig.json` はただのJSONファイルではありません。プロジェクトの性格を決定づける「設計図」です。

アプリケーションコード、テストコード、ビルドスクリプト。これらはすべてTypeScriptで書かれますが、それぞれ「必要な型定義」や「出力先」は微妙に異なります。これらを1つのファイルで管理しようとすると、`compilerOptions` が衝突し、保守性が極限まで下がります。

`extends` を使うことで、これらを「共通ベース」と「各環境用の差分」に分離できる。これが、堅牢なフロントエンド基盤を作る第一歩です。

2. 実務で使える「tsconfig 階層化」の黄金パターン

現場でよく採用する、最も美しく拡張性の高い構成を紹介します。ベース設定は `tsconfig.base.json` に逃がすのが鉄則です。

① ベース設定:tsconfig.base.json

まず、全プロジェクト共通の厳しい縛りを定義します。

{
“compilerOptions”: {
/ 厳格な型チェック。これがないとTSを使う意味が半減する /
“strict”: true,
“esModuleInterop”: true,
“skipLibCheck”: true,
“target”: “ESNext”,
“module”: “ESNext”,
“moduleResolution”: “bundler”,
“isolatedModules”: true
}
}

② アプリケーション設定:tsconfig.json

次に、実際に開発するコード用の設定です。`extends` でベースを読み込み、差分だけを書きます。

{
“extends”: “./tsconfig.base.json”,
“compilerOptions”: {
“outDir”: “./dist”,
“jsx”: “react-jsx” // React環境ならここに書く
},
“include”: [“src//”]
}

③ テスト設定:tsconfig.test.json

ここがポイントです。テストコードには「テスト用のライブラリの型」が必要ですが、それをメインの設定に入れるとビルド成果物に悪影響を与えかねません。

{
“extends”: “./tsconfig.base.json”,
“compilerOptions”: {
“types”: [“vitest/globals”, “testing-library__jest-dom”]
},
“include”: [“src//.test.ts”, “tests//”]
}

—

3. 現場でハマる「優先順位」の落とし穴

「継承したのに設定が反映されない!」というトラブルは、多くの場合、この優先順位の理解不足に起因します。

TypeScriptの解決ルール

1. 下位の設定が優先: `tsconfig.json`(子)で定義した値は、`tsconfig.base.json`(親)の値を常に上書きします。
2. 配列型のプロパティは結合されない: `include` や `exclude`、`types` などの配列型は、親の設定を完全に置き換えます。

  • これが一番の罠です。「ベース設定にある `include` に追加したい」と思って子設定で書くと、ベースの `include` が無視されます。この場合は、子側でも必要なパスをすべて書き直す必要があります。

4. 裏側で何が起きているのか?

TypeScriptのコンパイラが起動する際、内部的にはこの `extends` を再帰的に解決し、最終的に一つの巨大な設定オブジェクトをメモリ上に展開します。

ブラウザがどうこうというより、これはビルドツール(Webpack, Vite, esbuild)の型チェックフェーズでの話になりますが、「階層化されていることで、IDE(VSCodeなど)がファイルごとにどの設定を参照すべきか」を正確に判断できるようになります。

これにより、IDEのサジェストが「本番コードにテスト用メソッドが混ざる」といったミスを未然に防いでくれるわけです。これは開発体験(DX)に直結します。

—

シニアからのアドバイス:保守の極意

最後に一つだけ。`tsconfig.json` をいじる際は、「なぜこの設定が必要なのか」を必ずコメントに残してください。

例えば、`”allowJs”: true` にしているなら、「JSとの混在環境のため一時的に許可。半年後に再検証」といったメモがあるだけで、後任者は震えることなくリファクタリングができます。

設定ファイルは「書いたら終わり」のゴミ箱ではなく、チームの「規約」そのものです。ファイルを分割し、継承を活用し、不要な設定を削ぎ落とす。その泥臭い積み重ねが、半年後のあなたを救うことになります。

まずは今のプロジェクトの `tsconfig.json` を開き、共通部分を `base` に切り出すところから始めてみてください。きっと、コードベースが少しだけ「軽くなった」と感じるはずですよ。

それでは、また現場で会いましょう。ハッピー・コーディング!

コメント

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