tsconfig.json はTypeScriptプロジェクトの設定ファイルです。引数なしで tsc を実行すると、コンパイラーは現在のフォルダー(なければ親フォルダー)でこのファイルを探し、compilerOptions のオプションを読み込み、include に挙げられたファイルをチェックします。小さいながら完全な例です。
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"strict": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
この設定では、src 内のすべてのTypeScriptファイルが、ES2022のコードとして、Node.jsのモジュールルールに従い、strictのチェックをすべて有効にして、dist のJavaScriptにコンパイルされます。npx tsc --init を使うと、すべてのオプションにコメントが付いた、より長い初期ファイルが生成されます。
このファイルはコメント付きJSONです。// のコメント、/* */ のコメント、末尾のカンマがどれも使えます。
おすすめの初期設定
Node.jsのアプリケーションやスクリプトの場合です。
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"target": "es2024",
"lib": ["es2024"],
"module": "nodenext",
"types": ["node"],
"strict": true,
"noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"sourceMap": true
},
"include": ["src"]
}
Node.jsの型のために npm install --save-dev @types/node が必要です。module: "nodenext" では、package.json の "type" フィールドによって、.ts ファイルがESモジュール("type": "module")かCommonJS("type": "commonjs"、npm init -y が書き出す値)かが決まります。import と export を使う新しいプロジェクトでは "type": "module" にしましょう。
Vite、esbuild、webpackのようなバンドラーがビルドするコードでは、JavaScriptはバンドラーが書き出し、tsc はチェックだけを行います。
{
"compilerOptions": {
"target": "es2022",
"lib": ["es2022", "dom"],
"module": "preserve",
"noEmit": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
"skipLibCheck": true,
"jsx": "react-jsx"
},
"include": ["src"]
}
フレームワークのスターター(Vite、Next.js、Angular)は独自の tsconfig.json を生成します。置き換えるのではなく、それを出発点にしてください。
重要なオプション
| オプション | 役割 | TypeScript 7のデフォルト |
|---|---|---|
target | 出力するJavaScriptのバージョン。古いtargetでは新しい構文が書き換えられる | es2025 |
lib | チェッカーが知っている組み込みAPIの型(Array.prototype.at、Map、document) | target に対応したもの+DOM |
module | 出力するモジュールコードの種類と適用するモジュールのルール | esnext |
moduleResolution | importのパスをディスク上でどう探すか | 対応する module なら nodenext か node16、それ以外は bundler |
strict | strict系のチェックをまとめて有効にする | true |
rootDir | 構造がそのまま outDir に写されるフォルダー | tsconfig.json があるフォルダー |
outDir | .js(と .d.ts)ファイルの出力先 | 各ソースファイルの隣 |
include / exclude / files | プロジェクトに含めるファイル | フォルダー以下のすべての .ts ファイル |
types | importなしで読み込む @types パッケージ | [](なし) |
noEmit | チェックだけして何も書き出さない | false |
declaration | .d.ts 型宣言ファイルも書き出す | false |
sourceMap | デバッガー用の .js.map ファイルを書き出す | false |
esModuleInterop | CommonJSパッケージで import x from "cjs-package" を使えるようにする | true(無効にできない) |
skipLibCheck | node_modules 内のものも含め、.d.ts ファイルの型チェックを省略する | false |
targetとlib
target は出力を動かすJavaScriptのバージョンを指定します。targetより新しい構文は書き換えられます。"target": "es2017" なら、クラスフィールドや ??= は古いコードに変換されます。TypeScript 7が受け付ける一番低いtargetは es2015(es6)で、es5 は削除されました。
target は、足りない実行時のAPIを追加しません。それを記述するのは lib の役目で、実際に補うのはポリフィルの役目です。lib は、どの組み込みオブジェクトとメソッドが存在するかをチェッカーに教えます。デフォルトは target に従い、ブラウザーのDOMの型も含むので、自分で lib を設定しない限り、Node.jsのプロジェクトでも document の型チェックが通ります。lib より新しい標準のメソッドを使うとコンパイルエラーになります。
src/b.ts(1,24): error TS2550: Property 'toSorted' does not exist on type 'number[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2023' or later.
このドキュメントの実行可能な例は es2022 のlibを使っているので、toSorted、Object.groupBy、Set の新しいメソッドは使えません。
moduleとmoduleResolution
新しいコードで意味のある module の値は3つです。
nodenext: Node.jsで実行するコード向け。各ファイルは、拡張子(.mts、.cts)か一番近いpackage.jsonの"type"によって、Nodeと同じ判断でESMかCommonJSになります。ESモジュールの相対importにはファイル拡張子が必要で、ソースが.tsでも.jsと書きます(import { add } from "./math.js")。moduleResolutionは自動的にこれに合わせられます。preserve: バンドラーが処理するコード向け。importは書いたとおりに残され、解決には拡張子なしのimportを許すbundlerのルールが使われます。esnext: 素のESモジュールを出力し、解決にはbundlerを使います。moduleを設定しない場合のデフォルトです。
tsc --init の設定でよく最初に出るエラーは、npm init -y が "type": "commonjs" を書き出すことが原因です。
src/main.ts(1,10): error TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.
ファイルは import を使っているのに、package.json ではプロジェクトがCommonJSになっています。"type" を "module" に変えてください。importとexportの詳細はモジュールのページで解説しています。
strictとチェック系のオプション
"strict": true は一連のチェックをまとめて有効にします。noImplicitAny、strictNullChecks、strictFunctionTypes、strictBindCallApply、strictPropertyInitialization、strictBuiltinIteratorReturn、noImplicitThis、useUnknownInCatchVariables です。TypeScript 7ではデフォルトで、ここにある実行可能な例もすべて有効になっています。strictモード向けに書かれたコードは、存在しないかもしれない値を使う前に型を絞り込みます。
注釈がないと引数の型は推論できず、noImplicitAny がそれを報告します。
index.ts(2,17): error TS7006: Parameter 'n' implicitly has an 'any' type.
strict に便利なチェックがすべて含まれているわけではありません。追加する価値があるのは、noUncheckedIndexedAccess(配列の要素やインデックスシグネチャの参照が T | undefined 型になる)と exactOptionalPropertyTypes(オプショナルなプロパティに明示的に undefined を代入できなくなる)の2つで、tsc --init はどちらも有効にします。noUnusedLocals、noImplicitReturns、noFallthroughCasesInSwitch のようなスタイル系のチェックはデフォルトで無効です。
対象ファイル: include、exclude、rootDir、outDir
include も files もなければ、プロジェクトにはフォルダーとそのサブフォルダーにあるすべての .ts、.tsx、.d.ts ファイルが含まれます。node_modules は常に除外されます。outDir も除外されますが、それは exclude を設定していない間だけです。独自の exclude リストはこのデフォルトを置き換えるので、出力フォルダーもそこに加えてください。include と exclude にはglobパターンが使えます。
{
"include": ["src", "scripts/**/*.ts"],
"exclude": ["src/**/*.test.ts"]
}
exclude は include で見つかったものを絞り込むだけです。含まれているほかのファイルがimportしているファイルは、やはりコンパイルされます。
outDir は出力先で、rootDir はそこに写されるソースツリーの範囲です。"rootDir": "./src" なら、src/api/users.ts は dist/api/users.js になります。両方を設定しましょう。rootDir のデフォルトは tsconfig.json があるフォルダーなので、ソースが src にあるのに outDir だけを設定すると、TypeScript 7は次のエラーで停止します。
error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
出力のオプション: noEmit、declaration、sourceMap
"noEmit": trueにすると、tscは純粋な型チェッカーになります。JavaScriptを別のツール(バンドラー、tsx、Node.jsの型ストリッピング)が生成する場合に使います。"declaration": trueはモジュールごとに.d.tsファイル(コードを除いた型だけ)を書き出します。ライブラリの利用者が型を得られるように、ライブラリには必須です。declarationMapを加えると、.tsのソースへの「定義へ移動」のためのマップも出力されます。"sourceMap": trueは.js.mapファイルを書き出し、デバッガーやスタックトレースが.tsの行を指すようにします。"noEmitOnError": trueにすると、型エラーがある間は何も書き出しません。これがないと、tscはエラーを報告しつつJavaScriptも書き出します。
types、esModuleInterop、skipLibCheck
types には、importなしでグローバルに読み込む @types パッケージを並べます。TypeScript 7のデフォルトは空のリストなので、npm install --save-dev @types/node のあとに "types": ["node"] も加えます。そうしないと process や require は不明のままです(error TS2591: Cannot find name 'process')。Jestの describe のようにグローバル関数を持つテストランナーも同じリストに入れます。
esModuleInterop は、CommonJSパッケージのデフォルトimport(import express from "express")を使えるようにします。TypeScript 7では常に有効で、false にするとエラーになります。
skipLibCheck は宣言ファイルの型チェックを省略します。ビルドが速くなり、自分では直せない node_modules 内のエラーも避けられますが、2つのライブラリの型の衝突に気づけなくなります。ほとんどのプロジェクトは有効にしています。
extendsで設定を共有する
extends は別の設定を読み込み、その一部をこのファイルで上書きできるようにします。
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
compilerOptions はオプションごとにマージされますが、include、exclude、files は、このファイルで設定するとベースのものがマージされずに置き換えられます。ベースファイル内のパスは、ベースファイルからの相対パスとして解決されます。extends にはパッケージも指定できます。@tsconfig/bases プロジェクトは環境ごとに1つずつ公開していて、たとえば npm install --save-dev @tsconfig/node24 のあと "extends": "@tsconfig/node24/tsconfig.json" と書きます。
すべての extends とデフォルトを適用したあとの最終的な設定を確認するには、次を実行します。
npx tsc --showConfig
TypeScript 7で削除されたオプション
以下の設定はTypeScript 6で非推奨になり、TypeScript 7で削除されました。まだ使っている設定は error TS5108 や TS5102 で失敗します。たとえば Option 'baseUrl' has been removed. Please remove it from your configuration. です。
| 削除された設定 | 代わりに使うもの |
|---|---|
"target": "es5" | es2015 以上 |
"moduleResolution": "node"(node10)または "classic" | nodenext か bundler |
"module": "amd"、"umd"、"system"、"none" | nodenext、esnext、preserve。ほかの形式にはバンドラー |
baseUrl | tsconfigファイルからの相対パスで書いた paths |
outFile | バンドラー |
downlevelIteration | 不要。es2015 以上のtargetはイテレーションをネイティブにサポートする |
"esModuleInterop": false、"allowSyntheticDefaultImports": false、"alwaysStrict": false | その行を削除する。これらは常に有効 |
このリリースのほかの変更点(この表で扱っていない新しいデフォルトを含む)は、TypeScript 7のページにまとめています。
よくある質問
tsconfig.jsonとは何ですか?
TypeScriptプロジェクトの設定ファイルです。このファイルがあるフォルダーがプロジェクトのルートになり、compilerOptions でコンパイラーのチェックと出力の方法を、include、exclude、files でプロジェクトに含めるファイルを指定します。引数なしで tsc を実行すると、このファイルが読み込まれます。
tsconfig.jsonを作るには?
TypeScriptをインストールしたプロジェクトのフォルダーで npx tsc --init を実行します。推奨設定と各オプションのコメント付きで tsconfig.json が書き出されます。手で書いてもかまいません。{} もすべてデフォルトを使う有効なtsconfigです。
tsconfigのtargetには何を指定すればよいですか?
コードを動かす必要がある一番古いJavaScriptのバージョンです。最近のNode.jsなら es2022 以上で問題ありません。TypeScript 7のデフォルトは es2025 です。target は古いエンジン向けにどの新しい構文を書き換えるかを決め、デフォルトの lib(チェッカーが知っている組み込みAPIの集合)も決めます。
moduleとmoduleResolutionの違いは何ですか?
module はコンパイラーが書き出すモジュールコードの種類(ESの import/export かCommonJSの require)と、適用するモジュールのルールを決めます。moduleResolution は "./utils.js" や "lodash" のようなimportのパスをディスク上でどう探すかを決めます。Node.jsで実行するコードには nodenext、バンドラーが処理するコードには module: "preserve"(bundler の解決方法を含む)を使います。
tsconfig.jsonにコメントは書けますか?
書けます。コンパイラーはこのファイルをコメント付きJSONとして読むので、// と /* */ のコメントや末尾のカンマが使えます。tsc --init がコメントアウトされたオプションだらけのファイルを書き出すのはそのためです。ただし、厳密なJSONとして読むほかのツールはエラーになることがあります。