404 Not Found

404 Not Found


nginx

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 暗黙の thisany として扱うことを禁止
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.jsonextendstsconfig.jsonを継承し、targetmoduleなどのオプションのみを変更できます。これにより、設定の重複を回避できます。

📖 まとめ

📝 練習問題

  1. 基本演習(難易度 ⭐)tsc --init を使用してデフォルトの tsconfig.json ファイルを生成し、target を ES2020 に変更し、strict を有効にし、outDirdist に設定してください。簡単な TypeScript ファイルを作成し、コンパイルして、正常に動作することを確認してください。
  2. 上級演習(難易度 ⭐⭐):パスエイリアス @/*src/* をサポートする tsconfig.json ファイルを設定してください。src/utils/math.tssrc/main.ts を作成し、エイリアスを使用して math.ts から main.ts へ関数をインポートしてください。
  3. 課題(難易度:⭐⭐⭐): モノレポプロジェクトの構成階層を設計してください。ベースとなる tsconfig.base.json(共通オプション)、packages/app/tsconfig.json(ベースを継承、Reactフロントエンド)、packages/server/tsconfig.json(ベースを継承、Nodeバックエンド)の3つのサブプロジェクトを用意し、references を使用してこれら2つのサブプロジェクトを連携させてください。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%