tsconfig.json 推奨構成(2026年版)

TypeScript 6.0で多くのデフォルト値が変更され、設定がシンプルになりました。 以下は2026年の新規プロジェクト向け推奨構成です。

{
  "compilerOptions": {
    // TypeScript 6.0 からデフォルトで有効
    "strict": true,              // 全strictオプション一括有効化
    "target": "es2025",          // 6.0の新デフォルト
    "module": "esnext",          // 6.0の新デフォルト
    "moduleResolution": "bundler", // Vite/Next.js使用時

    // 追加推奨(6.0デフォルトに含まれない)
    "noUncheckedIndexedAccess": true,   // 配列・オブジェクトのアクセスにundefined追加
    "exactOptionalPropertyTypes": true, // ?プロパティの厳密化
    "noImplicitOverride": true,         // override キーワード必須化
    "noFallthroughCasesInSwitch": true, // switch文のフォールスルー禁止
    "verbatimModuleSyntax": true,       // import/export文をそのまま出力
    "erasableSyntaxOnly": true,         // Node.js native TS対応の準備

    // 出力
    "outDir": "dist",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}

strict モード全解説

strict: trueを有効にすると、以下の8つのオプションが一括で有効化されます。 TypeScript 6.0からはデフォルトでtrueです。

オプション 効果 検出できるバグ
noImplicitAny 暗黙のany型をエラーに 型なし関数引数、不正確な推論
strictNullChecks null/undefinedを明示的に扱う Cannot read property of null/undefined
strictFunctionTypes 関数パラメータの型を厳密チェック コールバックの型不一致
strictBindCallApply bind/call/applyの引数型チェック 動的呼び出しの型不整合
strictPropertyInitialization クラスプロパティの初期化漏れ検出 undefinedアクセス
noImplicitThis thisの型が不明な場合にエラー thisの暗黙的なany
alwaysStrict 全ファイルにJS strict mode付与 JS strictモードのバグ防止
useUnknownInCatchVariables catch変数をunknown型に エラーオブジェクトの誤った型仮定

Enum vs as const — 現代の選択

TypeScriptのenumは、設計目標「式レベルの構文追加を最小限に」に反する例外的な存在です。 ランタイムにJavaScriptコードを生成し、Tree-shakingが効きにくく、Node.jsの型ストリッピング(--strip-types)でもサポートされません。

観点 enum as const + typeof
ランタイムコード 生成する(逆引きマッピング等) JavaScriptオブジェクトのみ
Tree-shaking 効きにくい 通常通り動作
Node.js native TS 非対応 対応
型の柔軟性 限定的 ユニオン型として自由に利用可能
数値代入の安全性 任意の数値が代入可能(穴あり) リテラル型で厳密に制限
// ❌ 旧スタイル: enum
enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE",
  Pending = "PENDING",
}

// 数値enumの落とし穴
enum Direction { Up, Down, Left, Right }
const d: Direction = 999; // エラーにならない!

// ✅ 現代スタイル: as const + typeof
const Status = {
  Active: "ACTIVE",
  Inactive: "INACTIVE",
  Pending: "PENDING",
} as const;

type Status = (typeof Status)[keyof typeof Status];
// "ACTIVE" | "INACTIVE" | "PENDING"

// ランタイムオブジェクトとしてもユニオン型としても使える
function processStatus(status: Status) {
  if (status === Status.Active) {
    // ...
  }
}

moduleResolution — 正しい設定の選び方

用途 特徴
bundler Vite, Next.js, Webpack等 package.json の exports を尊重。拡張子不要
node16 / nodenext Node.js ライブラリ ESM/CJS両対応。拡張子必須
node(旧式) レガシー用途のみ exports 非対応。非推奨
classic(旧式) TypeScript 1.x互換 TS 7.0で削除予定
graph TD
  A{プロジェクトの種類は?} -->|Vite / Next.js / Webpack| B[bundler]
  A -->|Node.js ライブラリ| C[node16 / nodenext]
  A -->|Deno / Bun| D[bundler でOK]
  A -->|レガシープロジェクト| E[node(移行推奨)]

  style A fill:#eab308,stroke:#ca8a04,color:#000
  style B fill:#22c55e,stroke:#16a34a,color:#fff
  style C fill:#22c55e,stroke:#16a34a,color:#fff
  style D fill:#22c55e,stroke:#16a34a,color:#fff
  style E fill:#ef4444,stroke:#dc2626,color:#fff
moduleResolution の選び方 — プロジェクトの種類で決まる

初心者が詰まるポイント TOP10

# 落とし穴 対策
1 anyの乱用 unknown + 型ガードを使う
2 型アサーション(as)の多用 satisfiesや型ガードで代替
3 strictNullChecksを無効にする プロジェクト開始時からstrict: trueで
4 オブジェクト型にobjectを使う 具体的なインターフェースを定義する
5 過度なジェネリクス 型パラメータが2箇所以上で使われるか確認
6 interfacetypeの混乱 オブジェクト型はinterface、それ以外はtype
7 moduleResolution: nodeを使い続ける bundlerまたはnode16に移行
8 値と型の名前空間を混同 typeofで値から型を取得
9 @ts-ignoreの多用 @ts-expect-errorを使う(エラーが解消されたら教えてくれる)
10 型定義ファイル(@types/*)の入れ忘れ npm i -D @types/xxxを忘れずに

Declaration Files (.d.ts) — 型の橋渡し

.d.tsファイルは型宣言のみを含み、実行時コードは含みません。 JavaScriptライブラリにTypeScriptの型情報を提供する「橋渡し」の役割を果たします。

// types/my-untyped-lib.d.ts
// 型定義のないJSライブラリに型を付ける
declare module "my-untyped-lib" {
  export function doSomething(input: string): number;
  export interface Config {
    verbose: boolean;
    timeout: number;
  }
}

// 使用側
import { doSomething } from "my-untyped-lib";
const result = doSomething("hello"); // number型として推論される

理解度チェック

問題 0 / 50%
Q1

TypeScript 6.0 からの strict オプションのデフォルト値はどれですか?

キーボード: 1〜4 で選択、Enter で回答