tsconfig.jsonの読み方
この章の目次開く
- VS Codeはどうやって型エラーを表示しているのか
- 赤い波線がすべてTypeScriptとは限らない
- VS Codeが使っているtsconfigを確認する
- 設定ファイルを切り替えるコマンドではない
- tsconfig.dev.jsonをVS Codeの標準設定にできるか
- strictモード — まずこれを有効にする
- 既存プロジェクトで strict を有効にするとき
- target と module — 出力するJSの形式
- moduleResolution — importの解決方法
- paths と baseUrl — パスエイリアス
- パスエイリアスの解決はTypeScriptだけでは完結しない
- include と exclude
- フレームワークのtsconfig
- 実務でよく変更するオプション一覧
- ちゃんと使うためのポイント
- 参考リンク
tsconfig.json はTypeScriptプロジェクトの設定ファイルです。オプションが多く初見では圧倒されますが、実務で重要なものは限られています。
学習者tsconfig.json のオプションが多すぎて開く気が失せる…。全部理解しないとダメ?
先生全部覚える必要はない。まず strict を有効にして、あとはプロジェクトで問題が出たときにピンポイントで調べれば十分だよ。
VS Codeはどうやって型エラーを表示しているのか
VS CodeでTypeScriptファイルを開くと、tsc コマンドを実行していなくても、型エラーの赤い波線やコード補完が表示されます。この処理には、VS Codeに内蔵されているTypeScript拡張機能と、TypeScriptの tsserver が使われています。
VS Code
↓ ファイルを開く・文字を入力する・補完を要求する
VS Code内蔵のTypeScript拡張機能
↓ リクエストを送る
tsserver
↓ プロジェクトとファイルの状態を管理する
TypeScript Language Service
↓ 必要な構文解析・型チェックを行う
型エラー・補完候補・定義位置などをVS Codeへ返すtsserver は、エディタ向けに動き続けるTypeScriptのサーバープログラムです。開いているファイルやその変更内容、ファイル同士のつながりをメモリ上で管理し、VS Codeからの問い合わせに応答します。
その内部で、型エラーの検出、コード補完、定義への移動、名前の変更などを計算するAPIがTypeScript Language Serviceです。Language Serviceは独立して起動するサーバーではなく、tsserver が利用する機能です。
一方、tsc はターミナルから実行するTypeScriptコンパイラです。tsc と tsserver はTypeScriptの共通の構文解析・型チェック機能を利用しますが、目的と動き方が異なります。
tsc | tsserver | |
|---|---|---|
| 主な利用者 | 開発者やCI | VS Codeなどのエディタ |
| 動き方 | コマンドとして実行する | エディタを開いている間は動き続ける |
| 主な目的 | 型チェックとファイル出力 | エディタ操作への応答 |
| 提供するもの | 型エラー、コンパイル結果 | 型エラー、コード補完、定義への移動など |
したがって、VS Codeに表示されるTypeScript由来の赤い波線は、裏側で tsc を毎回実行した結果ではありません。tsserver がLanguage Serviceから取得し、VS Codeへ返した診断結果です。
VS Codeが使っているtsconfigを確認する
tsserver は、ファイルをTypeScriptプロジェクトの単位で管理します。通常は、そのファイルを対象に含む tsconfig.json を見つけ、そこに書かれた設定を型エラーやコード補完へ反映します。
現在開いているファイルにどの設定ファイルが適用されているかは、VS Codeで確認できます。
- 確認したい
.tsまたは.tsxファイルを開く - コマンドパレットを開く(macOSは
Command + Shift + P、Windows/LinuxはCtrl + Shift + P) TypeScript: Go to Project Configuration (tsconfig)を実行する
そのファイルが所属しているTypeScriptプロジェクトの tsconfig.json が開きます。複数の設定ファイルがあるプロジェクトでは、予想した設定が適用されているかを確認するのに便利です。
設定ファイルが見つからない場合、VS Codeはそのファイルが設定済みのTypeScriptプロジェクトに属していないことを通知します。このとき tsserver は、開いているファイルを推論されたプロジェクトとして扱い、既定の設定でコード補完や型チェックを行います。
tsconfig.dev.jsonをVS Codeの標準設定にできるか
学習者プロジェクトルートの tsconfig.json を tsconfig.dev.json に変更して、VS Codeでも標準の設定ファイルとして使うことはできる?
先生tsc には任意の設定ファイルを指定できるけれど、VS Codeに任意のファイル名を標準設定として直接指定することはできないよ。VS Codeにも使わせるなら、入口となる tsconfig.json を残そう。
tsc では、--project(省略形は -p)に設定ファイルのパスを渡せます。そのため、任意の名前の設定ファイルを使って型チェックできます。
npx tsc -p tsconfig.dev.jsonしかし、これはこのコマンドで使う設定ファイルを指定しているだけです。VS Codeの tsserver に対して、tsconfig.dev.json をこのプロジェクトの標準設定として直接指定する一般的な設定はありません。tsconfig.dev.json だけに改名すると、VS Codeからは自動認識されなくなります。
設定の本体を tsconfig.dev.json に置きたい場合は、プロジェクトルートに入口となる tsconfig.json を残し、extends で読み込む方法が確実です。
// tsconfig.json
{
"extends": "./tsconfig.dev.json"
}これなら、VS Codeは tsconfig.json をプロジェクト設定として認識し、その先の tsconfig.dev.json に書かれた設定も適用します。TypeScript: Go to Project Configuration (tsconfig) を実行すると、入口である tsconfig.json が開きます。
strictモード — まずこれを有効にする
strict: true は、複数の厳格チェックをまとめて有効にするフラグです。
{
"compilerOptions": {
"strict": true
}
}strict: true が有効にする主要オプション:
| オプション | 何をチェックするか |
|---|---|
strictNullChecks | null / undefined を型レベルで区別する |
noImplicitAny | 型推論できないものに暗黙の any を禁止する |
strictFunctionTypes | 関数の引数型を厳密にチェックする |
strictPropertyInitialization | classプロパティの初期化漏れを検出する |
// strictNullChecks: true の場合
function greet(name: string | null) {
// ❌ name.toUpperCase(); // Object is possibly 'null'
// ✅
if (name) {
name.toUpperCase();
}
}
// noImplicitAny: true の場合
// ❌ function process(data) {} // Parameter 'data' implicitly has an 'any' type
// ✅
function process(data: unknown) {}target と module — 出力するJSの形式
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext"
}
}| オプション | 決めること | よくある値 |
|---|---|---|
target | コンパイル先のJSバージョン | ES2020, ES2022, ESNext |
module | 出力するモジュール形式 | ESNext, CommonJS, Node16 |
target を低くすると、async/await がジェネレータに変換されるなど出力が複雑になります。モダンブラウザやNode.js 18+なら ES2022 以上で問題ありません。
学習者target と module の違いがよく分からない…。どちらもES何とかを指定するけど何が違うの?
先生target は「どのバージョンのJSに変換するか」で、module は「import/exportをどの形式で出力するか」。Next.jsやViteならフレームワークが適切なデフォルトを設定してくれるから、そのまま使えばOK。
moduleResolution — importの解決方法
{
"compilerOptions": {
"moduleResolution": "bundler"
}
}| 値 | 使う場面 |
|---|---|
node | 従来のNode.js(CommonJS中心) |
node16 / nodenext | Node.js 16+のESM対応 |
bundler | Vite, Next.js, webpackなどバンドラー経由 |
bundler はバンドラーが解決してくれる前提で、拡張子なしの import や package.json の exports フィールドを柔軟に扱います。フロントエンド開発では bundler が推奨されています。
paths と baseUrl — パスエイリアス
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}これで import { Button } from '@/components/Button' のようなエイリアスが使えます。
include と exclude
{
"include": ["src/**/*", "types/**/*"],
"exclude": ["node_modules", "dist"]
}include に指定したパターンに一致するファイルだけがコンパイル対象になります。exclude は include の結果からさらに除外するファイルを指定します。
フレームワークのtsconfig
Next.jsやViteは、プロジェクト作成時にtsconfigを自動生成します。
// Next.js が生成する tsconfig.json(抜粋)
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"moduleResolution": "bundler",
"jsx": "preserve",
"strict": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
フレームワークが生成したtsconfigは理由があってその値になっているため、意味が分からないまま変更すると問題が起きやすいです。変更するときは、そのオプションが何を制御しているかを確認してから行います。
実務でよく変更するオプション一覧
| オプション | 用途 | よくある変更 |
|---|---|---|
strict | 厳密な型チェック | 新規は true、レガシーは段階的に |
target | JS出力バージョン | 環境に合わせて ES2022 以上 |
paths | パスエイリアス | @/* を追加 |
skipLibCheck | .d.ts のチェック省略 | ビルド高速化のため true |
noUncheckedIndexedAccess | 配列・オブジェクトのアクセスに undefined を含める | 安全性を上げるなら true |
verbatimModuleSyntax | import type の明示を強制 | バンドルサイズ最適化 |
ちゃんと使うためのポイント
-
まず
strict: trueを有効にする。新規プロジェクトでは必須 - フレームワーク生成のtsconfigは理解してから変更する
moduleResolution: "bundler"がフロントエンド開発の現在の推奨pathsの設定はTypeScriptだけでなくバンドラー側も合わせる- 困ったときは公式ドキュメントのTSConfig Referenceを確認する
参考リンク
- TSConfig リファレンス(日本語) — 全コンパイラオプションの公式リファレンス
- What is a tsconfig.json(英語) — tsconfig.jsonの役割の公式説明
- Standalone Server(tsserver)(英語) — エディタとtsserverが通信する仕組み
- Transpiling TypeScript(英語) — VS CodeのTypeScript対応とtsconfigの解説