【実務・中級編】 compilerOptions.libの設定 – TypeScript実践ガイド

TypeScriptの `lib` 設定:君のプロジェクトの「呼吸」を制御する場所

やあ。現場でコードを書いていると、つい `tsconfig.json` は「最初に作ってから放置」しがちだよな。わかるよ。だが、中級者から一歩先へ進むなら、その中でも特に重要な `compilerOptions.lib` について、一度立ち止まって深く理解しておく必要がある。

多くのエンジニアが「なんとなく」で設定しているこの項目。実はこれ、「そのプロジェクトがどの環境(ランタイム)を前提に動くのか」をTypeScriptに宣言する、いわば憲法のようなものなんだ。

なぜ `lib` を正しく設定しなければならないのか

TypeScriptの `lib` は、コンパイル時に組み込む「型定義(d.ts)」のリストだ。これを指定しないと、TSはデフォルトで「このプロジェクトがどの環境で動くか」を推測する。だが、この推測に頼りすぎると、後々「ブラウザでしか動かないはずのコードがNode.jsでコンパイル通ってしまう」「本来は使えないはずのAPIが補完に出てきてしまう」といった事故が起きる。

いいか、「何ができるか」を制限することは、バグを防ぐ最強の防御策なんだ。

実務で使い倒すための `tsconfig.json` 設定例

例えば、モダンなブラウザ向けのSPA開発であれば、最小限かつ必要なものだけを明示的に指定するのがプロの流儀だ。以下に、現代のフロントエンド開発で最も堅実な設定例を置いておく。

{
“compilerOptions”: {
“target”: “ES2022”, // 出力されるJSのバージョン
“lib”: [
“ES2022”, // モダンなECMAScript機能(Promise.allSettled等)
“DOM”, // window, documentなどのDOM API
“DOM.Iterable” // NodeListなどをfor…ofで回すために必須
],
“strict”: true
}
}

なぜ `DOM.Iterable` が必要なのか?

これを知らないジュニア層は多い。例えば `document.querySelectorAll` が返す `NodeList` を、ES6のループで回したいとするだろう? `DOM.Iterable` がないと、TSは「それは反復可能(Iterable)じゃないよ」と怒り出す。これを許可することで、ブラウザのAPIを現代的なJSの書き方で安全に扱えるようになるんだ。

Node.js環境とフロントエンド環境が混在する場合の「罠」

もし君がNext.jsやViteを使っていて、かつNode.jsのスクリプトも同一リポジトリで管理しているなら、`lib` の設定だけでは足りない。

ブラウザの `window` オブジェクトをNode.js環境で参照するコードを書いても、`lib` に `DOM` を含めている限り、TSは「エラー」を吐いてくれない。ここで大事なのは、「TSの型定義」と「実行時のランタイム」を切り離して考えることだ。

もしプロジェクトの構造が複雑なら、`tsconfig.json` を継承(`extends`)させるのが定石だ。

  • `tsconfig.base.json` (共通設定)
  • `tsconfig.web.json` (`lib: [“DOM”, …]` を含む)
  • `tsconfig.node.json` (`lib: [“ESNext”]` のみ、DOMを含まない)

こうやって物理的に型空間を分離すれば、Node.js用のコードで誤って `window` を叩くような凡ミスは二度と起こらなくなる。

最後に:シニアからのアドバイス

「公式ドキュメントに書いてあるから」といって、不要なライブラリを全部詰め込んでいないか?

例えば、IE11のサポートを終了したなら `ES5` や `ScriptHost` といったレガシーなライブラリ定義は `lib` から削ぎ落とすべきだ。不要な型定義は、エディタの補完候補を汚し、意図せぬAPIの利用を許してしまう。

「必要なものだけを定義し、それ以外は存在しないものとして扱う」

この厳格さが、大規模開発でチームのコード品質を維持する秘訣だ。まずは今すぐ、君の `tsconfig.json` を開いて `lib` の中身をチェックしてみてくれ。そこに不要な遺物を見つけたら、それが君のプロジェクトをよりクリーンにするための、最初の一歩だ。

技術は常に進化している。設定ファイル一つとっても、そこに君の哲学を込めていこうぜ。応援している。

コメント

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