TypeScriptのtsconfig.jsonに関する詳細な解説
tsconfig.json は、TypeScript プロジェクトの設定の中核となるファイルです。このファイルは、コンパイラに対して、コードのコンパイル方法、型のチェック方法、および結果の出力方法を指示します。TypeScript プロジェクトを円滑に実行するためには、これらの設定オプションを理解することが不可欠です。
1. tsconfig.json の基礎
(1) 設定ファイルを作成する
BASH
# Automatically Generate Default Configuration
tsc --init
# Generate a detailed configuration with comments
tsc --init --typescript
(2) 基本構造
JSON
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
(3) 最上位フィールド
| フィールド | 説明 |
|---|---|
compilerOptions |
コンパイラのオプション |
include |
含まれるファイル(globモード) |
exclude |
除外ファイル |
files |
明示的に指定されたファイルの一覧 |
references |
プロジェクトのリファレンス (モノレポ) |
extends |
別の設定ファイルから継承する |
2. コアコンパイルオプション
(1) ターゲット—コンパイルターゲット
コンパイルされた JavaScript のバージョンを指定してください:
JSON
{
"compilerOptions": {
"target": "ES2020"
}
}
| 値 | 説明 | 推奨されるシナリオ |
|---|---|---|
"ES5" |
旧バージョンのブラウザに対応 | IE11に対応 |
"ES2018" |
最新のブラウザ | 一般的なWebプロジェクト |
"ES2020" |
最新の安定版機能 | おすすめ |
"ESNext" |
最新の提案機能 | 最先端のプロジェクト |
💡 ヒント:
target オプションは、構文変換(例:矢印関数 → 通常の関数)にのみ影響し、型チェックには影響しません。型チェックは lib オプションによって制御されます。
(2) モジュール—モジュールシステム
JSON
{
"compilerOptions": {
"module": "ESNext"
}
}
| 値 | 説明 | 推奨されるシナリオ |
|---|---|---|
"CommonJS" |
Node.js のデフォルト | Node プロジェクト |
"ESNext" / "ES2015" |
ESモジュール | ブラウザ/Deno/Vite |
"UMD" |
汎用モジュール | ライブラリのリリース |
"System" |
SystemJS | レガシー・モジュール・ローダー |
(3) moduleResolution—モジュールの解決戦略
JSON
{
"compilerOptions": {
"moduleResolution": "node"
}
}
| 値 | 説明 |
|---|---|
"node" |
Node.js スタイル(推奨) |
"classic" |
旧TSスタイル(推奨されません) |
"bundler" |
Vite/esbuild およびその他のビルドツール (TS 5.0+) |
(4) lib—型ライブラリ
利用可能な組み込み型の宣言を指定してください:
JSON
{
"compilerOptions": {
"lib": ["ES2020", "DOM", "DOM.Iterable"]
}
}
| 値 | 指定された型 |
|---|---|
"ES2020" |
Promise、Array.flat、BigInt など |
"DOM" |
document、window、HTMLElement など |
"DOM.Iterable" |
NodeList の for...of |
"ES2020.String" |
ES2020 の文字列メソッド |
"ES2020.Promise" |
Promise.allSettled など |
💡 ヒント:
target を指定すると、対応する lib が自動的に含まれます。もし lib を明示的に指定した場合、lib は自動的に含まれなくなるため、必要なライブラリをすべて手動で列挙する必要があります。Web プロジェクトでは通常、["ES2020", "DOM"] が必要です。
(5) outDir および rootDir
JSON
{
"compilerOptions": {
"outDir": "./dist", // Compilation Output Directory
"rootDir": "./src", // Source Code Root Directory(Preserve the directory structure)
"declaration": true, // Generate .d.ts Statement
"sourceMap": true // Generate .js.map Source Code Mapping
}
}
3. 厳格モードのオプション
(1) 厳格モードが完全に有効化されている
JSON
{
"compilerOptions": {
"strict": true
}
}
strict: true は、以下のオプションをすべて同時に有効にするのと同じ効果があります:
| オプション | 説明 |
|---|---|
strictNullChecks |
null/undefined を他の型に代入することはできません |
strictFunctionTypes |
関数引数の逆引き |
strictBindCallApply |
bind/call/apply の厳密なチェック |
strictPropertyInitialization |
クラスのプロパティを初期化する必要があります |
noImplicitAny |
暗黙的 any は禁止 |
noImplicitThis |
暗黙の this を any として扱うことを禁止 |
alwaysStrict |
「use strict」を出力 |
(2) 各ポイントの理解
TYPESCRIPT
// strictNullChecks: true
let name: string = null; // ❌ null Cannot be assigned string
let name2: string | null = null; // ✅ Explicit Declaration
// noImplicitAny: true
function greet(name) { // ❌ The parameter is implicitly set to any
return name;
}
function greet2(name: string) { // ✅ Explicit Annotation
return name;
}
// strictPropertyInitialization: true
class User {
name: string; // ❌ Property not initialized
age: number = 0; // ✅ Has an initial value
}
📌 推奨:すべての新規プロジェクトで
strict を有効にしてください。 これは TypeScript の型安全性の基盤となるものです。初期段階で型注釈を追加するのに多少の手間がかかるかもしれませんが、これにより多数の実行時エラーを防ぐことができます。
▶ 例:ストイックモード適用前後の比較
TYPESCRIPT
// strict: false — the following code does not generate any errors, but it may crash during execution.
let name: string = null as any; // Runtime name.toUpperCase() Breakdown
function greet(user) { // user Implicit any
return user.name; // No type checking
}
// strict: true — captured at compile time
let name2: string | null = null; // ✅ Must be explicitly declared null
function greet2(user: { name: string }) { // ✅ Parameters must be labeled
return user.name;
}
4. モジュールとパスの設定
(1) パスマッピング
JSON
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"],
"@components/*": ["src/components/*"]
}
}
}
(2) resolveJsonModule
JSON
{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true
}
}
TYPESCRIPT
// Import Allowed JSON Documents
import config from "./config.json";
console.log(config.port); // ✅
(3) allowJs と checkJs
JSON
{
"compilerOptions": {
"allowJs": true, // Allow compilation JS Documents
"checkJs": false // Do not check JS File Type(Compile Only)
}
}
💡 目的: JSプロジェクトをTSへ段階的に移行する際は、まず
allowJsを有効にしてTSとJSを共存させ、その後徐々に型を追加していく。
5. コード品質に関するオプション
JSON
{
"compilerOptions": {
"noUnusedLocals": true, // Error: Unused local variables
"noUnusedParameters": true, // Error: Unused function parameters
"noImplicitReturns": true, // Error: Function branch does not return a value
"noFallthroughCasesInSwitch": true, // Error: switch fallthrough
"forceConsistentCasingInFileNames": true // File names must be case-sensitive
}
}
(1) デモ
TYPESCRIPT
// noUnusedLocals: true
let unused = 42; // ❌ Unused variables
// noUnusedParameters: true
function handler(event: Event) { // ❌ event Unused
console.log("Trigger");
}
// Fix: Use _ prefix tag
function handler2(_event: Event) { // ✅ _ The prefix does not cause an error
console.log("Trigger");
}
// noImplicitReturns: true
function getGrade(score: number): string {
if (score >= 90) return "A";
if (score >= 80) return "B";
// ❌ Missing else Branched return
}
// noFallthroughCasesInSwitch: true
switch (action) {
case "create":
createItem();
// ❌ Missing break——case Penetration
case "update":
updateItem();
break;
}
6. 一般的な設定テンプレート
(1) Node.js バックエンドプロジェクト
JSON
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
(2) React フロントエンドプロジェクト (Vite)
JSON
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
(3) ライブラリプロジェクト(npmパッケージの公開)
JSON
{
"compilerOptions": {
"target": "ES2018",
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"declarationDir": "./dist/types",
"outDir": "./dist/esm",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}
❓ よくある質問
Q
strict を有効にすると、コードの記述が難しくなりますか?A 当初は(特に null チェックにおいて)型注釈を多く記述する必要が生じるかもしれませんが、長期的には実行時のバグを大幅に減らすことができます。最初から
strict を有効にすることをお勧めします。一度慣れてしまえば、使っていないとむしろ違和感を感じるようになるでしょう。プロジェクトがすでに大規模な場合は、段階的に有効にすることができます。まず noImplicitAny を有効にし、次に strictNullChecks を有効にし、最後に strict を完全に有効にしてください。Q noEmitとは何ですか?Viteプロジェクトはなぜ立ち上げられたのですか?
A
noEmit: true を使用すると、TypeScriptはJSファイルを出力せずに型チェックのみを行うことができます。Viteプロジェクトでは、コンパイルとバンドリングにVite(esbuild)を使用し、tscは型チェックのみを担当するため、tscがファイルを出力する必要はありません。CIでの型チェックにはtsc --noEmitを使用し、開発中のリアルタイムコンパイルはViteに任せましょう。Q skipLibCheck を有効にするべきですか?
A 有効にすることをお勧めします。skipLibCheck は
.d.ts ファイルの型チェックをスキップするため、コンパイル速度を大幅に向上させることができます。欠点としては、サードパーティの型宣言におけるエラーを見逃す可能性があることですが、そのリスクは極めて低いです(@types パッケージはコミュニティによるレビューを経ています)。大規模なプロジェクトで skipLibCheck を有効にすると、コンパイル時間を 30% 以上短縮できます。Q 設定の継承に
extends を使用する目的は何ですか?A プロジェクトに複数の
tsconfig ファイル(例:フロントエンド、Node スクリプト、テストなど)がある場合、extends を使用して基本設定を共有し、相違点のみを上書きします。tsconfig.node.jsonはextendsやtsconfig.jsonを継承し、targetやmoduleなどのオプションのみを変更できます。これにより、設定の重複を回避できます。📖 まとめ
tsconfig.jsonは TypeScript プロジェクトの設定ハブであり、compilerOptions、include、excludeの 3 つの主要なフィールドで構成されています。targetは JavaScript のバージョンを制御し、moduleはモジュールシステムを制御し、libは利用可能な型ライブラリを制御しますstrict: trueすべての厳格なチェックを有効にする—新規プロジェクトでは必ず有効にする必要があります- パスマッピング(baseUrl + paths)では、エイリアスを使用して長い絶対パスを置き換えます
- コード品質に関するオプション(noUnusedLocals や noImplicitReturns など)がさらに強化されました
- プロジェクトの種類によって、推奨される設定テンプレートが異なります。Nodeバックエンド、Reactフロントエンド、ライブラリプロジェクトなどです。
📝 練習問題
- 基本演習(難易度 ⭐):
tsc --initを使用してデフォルトのtsconfig.jsonファイルを生成し、targetを ES2020 に変更し、strictを有効にし、outDirをdistに設定してください。簡単な TypeScript ファイルを作成し、コンパイルして、正常に動作することを確認してください。 - 上級演習(難易度 ⭐⭐):パスエイリアス
@/*→src/*をサポートするtsconfig.jsonファイルを設定してください。src/utils/math.tsとsrc/main.tsを作成し、エイリアスを使用してmath.tsからmain.tsへ関数をインポートしてください。 - 課題(難易度:⭐⭐⭐): モノレポプロジェクトの構成階層を設計してください。ベースとなる
tsconfig.base.json(共通オプション)、packages/app/tsconfig.json(ベースを継承、Reactフロントエンド)、packages/server/tsconfig.json(ベースを継承、Nodeバックエンド)の3つのサブプロジェクトを用意し、referencesを使用してこれら2つのサブプロジェクトを連携させてください。



