tsconfig.json は、TypeScript のプロジェクトの設定ファイルです。「どのファイルを対象にするか」と、「TypeScript にどんな決まりで調べさせるか」を書きます。TypeScript の公式の文書では、tsconfig.json があるフォルダが、TypeScript のプロジェクトの根元(ルート)になります。Vite や Next.js でプロジェクトを作ると、最初から入っているファイルです。
この記事は、そのファイルを開いて「これは何?」となった初心者に向けて、書き方ではなく読み方に絞って書きました。Vite の react-ts のひな形(3 つに分かれています)と、Next.js のひな形を、上から順に読みます。6.0・7.0 で変わった既定値(初期値)の詳しい話は、TypeScript 7 の記事に任せます。
手元で確かめた結果は、macOS 14.4.1・Node.js 24.13.1・npm 11.8.0・TypeScript 7.0.2 のものです(2026年10月19日)。Windows と Linux では流していません。版が動く話には「2026年10月時点」と添えます。
- tsconfig.json が決めること(対象のファイルと、コンパイラの設定)と、
tscが tsconfig.json を探すしくみ - Vite のひな形が tsconfig を 3 つに分けている形の読み方と、引数なしの
npx tscが型の誤りを見つけない落とし穴 - Next.js のひな形の tsconfig.json に並ぶ項目の読み方
target・module・moduleResolution・paths・strict・noEmitなど、よく見る項目の意味- ひな形によって、入る TypeScript の版が違うこと(2026年10月19日時点)
tsconfig.json とは?何を決めるファイル?
TypeScript は、JavaScript に型の書き方を足した言語です。コンパイラ(tsc コマンド)は、.ts のファイルの型の誤りを調べ、.js のファイルに変換する道具です。この「型の誤りを調べること」を、型チェックと呼びます。tsconfig.json は、そのコンパイラに渡す設定を、JSON の形で書いたファイルです。
公式の文書によると、tsconfig.json は、対象にするファイル(ルートのファイル)と、コンパイラの設定(compilerOptions)を決めます。compilerOptions は書かなくてもよく、書かなければコンパイラの既定値が使われます。JavaScript のプロジェクトでは、ほぼ同じ働きの jsconfig.json も使えます。.js・.ts などの拡張子の違いは、こちらの記事で説明しています。
大まかな形は、次のとおりです(Next.js のひな形から、いくつかの項目だけを抜きました。include も一部を省いています)。
{
"compilerOptions": {
"strict": true,
"noEmit": true
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
compilerOptions: コンパイラの設定。項目は、この記事の後半で読みますinclude・exclude・files: 対象にするファイルを決める項目extends・references: ほかの設定ファイルと、つなぐ項目
新しい tsconfig.json のひな形は、tsc --init で作れます。7.0.2 が作る主な項目は、TypeScript 7 の記事に載せています。
Vite と Next.js のひな形で、TypeScript の版は違う?
tsconfig.json の読み方は、入っている TypeScript の版で変わります。2026年10月19日時点で、TypeScript の安定版(npm の latest)は 7.0.2(2026年7月8日)です。ところが、ひな形を作る道具が入れる版は、道具によって違います。
| ひな形を作る道具 | 入る TypeScript の版(2026年10月19日時点) |
|---|---|
npm create vite の react-ts(create-vite 9.3.0、2026年10月19日) | ~7.0.2 |
| create-next-app 16.4.2(2026年10月15日) | ^5(いま入るのは 5.9.3) |
create-vite は、9.0.4〜9.2.1 では TypeScript 6(~6.0.2)を、9.0.3 までは 5.9(~5.9.3)を入れていました。作った時期が違う Vite のプロジェクトは、入っている版が違うことがあります。Vite のひな形の入れ方と、要る Node.js の版は、Vite の記事で説明しています。create-next-app で作る手順は、Next.js 16.4 の記事で説明しています。
この違いは、読み方に効きます。たとえば strict(あとで説明します)の既定値は、6.0 から true で、5.9 までは false でした。Vite のひな形に strict の行が無いのは、TypeScript 6 に上げた create-vite 9.0.4 で、既定値が true になった設定を tsconfig から消したためです(Vite の Pull Request #22110 の本文より)。Next.js のひな形で入るのは 5 系で、5 系の既定は false です。このひな形では、"strict": true の行があるので、strict が有効になります。
自分のプロジェクトの版は、次のコマンドで確かめられます(TypeScript 7.0.2 の出力)。
$ npx tsc --version
Version 7.0.2
tsc は tsconfig.json をどう見つける?設定を確かめるには?
ファイル名を渡さずに tsc と打つと、tsc はいまのフォルダから親のフォルダへとさかのぼって、tsconfig.json を探します。tsconfig.json の無い子フォルダで tsc --showConfig を打つと、親の tsconfig.json の中身が出ました(TypeScript 7.0.2)。
探す場所を指定したいときは、-p(--project)を使います。tsconfig.json のあるフォルダか、設定の .json ファイル(名前は何でもよい)を渡せます。
npx tsc -p tsconfig.app.json
存在しないファイルを渡すと、error TS5058: The specified path does not exist: … になります。なお、tsconfig.json があるフォルダで tsc foo.ts のようにファイル名を渡す書き方は、6.0 から変わりました。くわしくは TypeScript 7 の記事にあります。
設定の確かめには、次の 2 つのコマンドが役に立ちます。
| コマンド | 何をするか |
|---|---|
tsc --showConfig | ビルドせずに、最終的な設定を表示する。extends を合わせたもの、既定から導かれるものも含む |
tsc --listFilesOnly | 対象になるファイルの名前を表示して、止まる |
--showConfig の出力を、Vite のひな形で見ます(npx tsc --showConfig -p tsconfig.app.json、TypeScript 7.0.2)。
{
"compilerOptions": {
"allowArbitraryExtensions": true,
"allowImportingTsExtensions": true,
"erasableSyntaxOnly": true,
"jsx": "react-jsx",
"lib": [
"es2023",
"dom"
],
"module": "esnext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"skipLibCheck": true,
"target": "es2023",
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"types": [
"vite/client"
],
"verbatimModuleSyntax": true,
"isolatedModules": true,
"preserveConstEnums": true
},
"files": [
"./src/App.tsx",
"./src/main.tsx"
],
"include": [
"src"
]
}
読みどころは 3 つです。
- ファイルに書いていない
isolatedModulesとpreserveConstEnumsが、trueで足されて出ています。verbatimModuleSyntaxから導かれたものです includeの"src"から、filesに実際のファイル(src/App.tsxとsrc/main.tsx)が並びました- 7.0.2 の
--showConfigには、既定がtrueのstrictの行が出ません。出ていなくても、strictは有効です(あとの「型チェックの厳しさ」で確かめます)。出ていない項目は、無効とは限りません
対象のファイルを決める項目は?(files・include・exclude)
どのファイルを対象にするかは、files・include・exclude の 3 つで決まります。
| 項目 | 読み方 |
|---|---|
files | 対象にするファイルを、1 つずつ並べる。1 つでも見つからないとエラーになる。ファイルが少ないとき向けで、たくさんあるなら include を使う |
include | 対象にするファイル名・パターンの一覧。tsconfig.json のあるフォルダからの相対で読む。*・?・**/ が使える。既定は、files があれば []、無ければ **/*(すべて) |
exclude | include で見つけたものから外す |
拡張子もワイルドカードも無い最後の部分は、フォルダとみなされ、その中の .ts・.tsx・.d.ts が入ります。Vite のひな形の "include": ["src"] は、この形です。
exclude は、「入れない仕組み」ではありません。 外したファイルでも、コードの中で import されたり、files に書かれたりすれば、対象に入ります。
設定を引き継ぐ・分けるには?(extends・references)
extends: ほかの設定ファイルを引き継ぐ
extends は、ほかの設定ファイルを引き継ぐ項目です。先に元のファイルを読み、引き継ぐ側で上書きします。相対パスは、それが書かれたファイルからの相対で読まれます。compilerOptions は、元の設定に引き継ぐ側が足す・上書きします。files・include・exclude は、引き継ぐ側のもので置き換わり(足し合わせません)、references は引き継がれません。
たとえば、Vite のひな形の tsconfig.app.json を引き継いで、paths だけを足したファイル(tsconfig.paths.json)を作ります。
{
"extends": "./tsconfig.app.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}
このファイルの --showConfig には、元の設定に paths が足されて出ました(TypeScript 7.0.2)。include は元のものです。
実行環境ごとの「土台の設定」が github.com/tsconfig/bases にあり、extends で使えると、公式は書いています。公式の例は古い Node.js 向けの設定なので、いまの版の中身は、この記事では確かめていません。
references: 設定を分けて、つなぐ
references(プロジェクト参照)は、プログラムを小さなまとまりに分ける仕組みです。各 path には、tsconfig.json のあるフォルダか、設定ファイルそのもの(名前は何でもよい)を書きます。
参照先までまとめて型チェック・ビルドするのは、tsc --build(短く tsc -b)です。参照されたプロジェクトを探し、古いものだけを正しい順で作ります。ふつうの tsc は、参照先を自動では作りません。
公式は、参照だけを並べて files を空の配列にした tsconfig.json(solution と呼ばれます)を根元に置くことを勧めています。空にしないと、同じファイルを 2 回コンパイルするためです。次の Vite のひな形は、この形です。
Vite のひな形(react-ts)の tsconfig を読む
次のコマンドで作ると(create-vite 9.3.0)、tsconfig が 3 つできます。--no-interactive --no-immediate は、質問に答えず、作るだけにする印です。付けないと、途中で質問が出ます。
npm create vite@latest my-app -- --template react-ts --no-interactive --no-immediate
3 つに分かれた形
根元の tsconfig.json は、"files": [] と references だけです。
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
前の節で説明した「solution」の形です。このファイル自身は、ファイルを 1 つも対象にしません。設定は、参照先の 2 つに書かれています。
| ファイル | 向け先 | 特徴 |
|---|---|---|
tsconfig.app.json | src の中のコード(ブラウザで動くアプリ) | lib は ["ES2023", "DOM"]、types は ["vite/client"]、moduleResolution は "bundler"、jsx は "react-jsx"。include は ["src"] |
tsconfig.node.json | vite.config.ts(Node.js で動く設定ファイル) | lib は ["ES2023"](DOM なし)、types は ["node"]、module は "nodenext"。include は ["vite.config.ts"] |
どちらも noEmit は true です。
なぜ 3 つに分けるの?
Vite の文書には、3 つに分ける理由の説明が見つかりませんでした(2026年10月19日時点)。理由として出せるのは、ひな形をいまの形に変えた Pull Request の本文です。Vite の Pull Request(#15913)の本文によると、次の事情でした。
- 以前は、
npm run buildで動くtscが、vite.config.tsの型の誤りで止まらなかった -bを付けて、参照先もまとめて型チェックするようにしたvite.config.jsとvite.config.d.tsが作られないように、根元の tsconfig.json を参照だけにした(create-vue というプロジェクトと同じ形)
これは文書ではなく Pull Request の本文なので、「そういう事情で変えた」という出どころ付きの説明として読んでください。
別の角度の説明として、TypeScript の公式の手引きには、「1 つの tsconfig.json が表せる環境は 1 つだけ」とあります。使えるグローバルやモジュールの動きが環境ごとに違うので、サーバー・DOM・テストなどは、それぞれ別の tsconfig.json に分け、プロジェクト参照でつなぐ、という説明です。tsconfig.app.json は DOM のあるブラウザ向け、tsconfig.node.json は DOM のない Node.js 向け、という分け方と合います。ただし、これは TypeScript の手引きの説明で、Vite の説明ではありません。
tsconfig.app.json の項目を上から読む
tsconfig.app.json の全文です(create-vite 9.3.0)。
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "es2023",
"lib": ["ES2023", "DOM"],
"module": "esnext",
"types": ["vite/client"],
"allowArbitraryExtensions": true,
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
/* Bundler mode */ のような行はコメントです。この形のファイルを、tsc はそのまま読めます(7.0.2)。「バンドラー」は、たくさんのファイルを 1 つにまとめる道具のことで、Vite もその仲間です。
| 項目 | 読み方 |
|---|---|
tsBuildInfoFile | 前回の型チェックの情報を残すファイルの場所。node_modules/.tmp に置く |
target・lib・module・moduleResolution・jsx | 出力の形と、import の探し方。あとの「よく見る項目の意味」で読む |
types・skipLibCheck・noEmit | 同じく、あとで読む |
allowImportingTsExtensions | import に .ts・.tsx を書けるようにする。noEmit のときなどに使える(あとで説明) |
verbatimModuleSyntax | 型だけの印(type)が付いていない import・export を、変換も省略もしない |
allowArbitraryExtensions | TypeScript の手引きが、バンドラーを使うアプリで勧めている項目のひとつ |
moduleDetection | この記事では意味を確かめていないので、説明しません |
「Linting」の 4 つは、コードの書き方の決まりです。
| 項目 | 読み方 |
|---|---|
noUnusedLocals | 使っていない変数をエラーにする |
noUnusedParameters | 使っていない引数をエラーにする。_ で始まる名前は除く |
erasableSyntaxOnly | 消すだけで JavaScript になる書き方だけに絞る。Node.js は 23.6 から TypeScript のファイルを直接動かせますが、その形だけが対象です |
noFallthroughCasesInSwitch | switch の case の抜け忘れをエラーにする |
Vite は tsconfig をどう使う?
Vite の文書によると、Vite 自身も tsconfig を読みます。
- ファイルごとに、「いちばん近い親の tsconfig.json のうち、そのファイルに当てはまるもの」を使い、その
referencesの先も見る - tsconfig の
targetは見ません。開発中はoxc.target、ビルドはbuild.targetで指定する pathsを使うのは、resolve.tsconfigPaths: trueを指定したときだけ- Vite は
.tsを JavaScript に変換するだけで、型チェックはしません。ファイルごとの変換と、全体を見る型チェックは、仕組みが違うためです
引数なしの npx tsc は、型の誤りを見つけない
ここが、初心者のはまりどころです。Vite のひな形で、-b を付けない npx tsc は、型の誤りがあっても何も表示せず、終了コード 0 で終わります(手元の結果。TypeScript 7.0.2・macOS)。
理由は、根元の tsconfig.json が "files": [] と references だけだからです。引数なしの tsc は根元の tsconfig.json を読みますが、そこには対象のファイルが 1 つもなく、参照先は自動では作られません。
誤りを入れて比べます。src/oops.ts を足しました。tsconfig.app.json の include の "src" に入るファイルです。
export const count: number = "3";
export function double(x) {
const unused = 1;
return x * 2;
}
$ npx tsc
(何も表示されない。終了コードは 0)
$ npx tsc -b
src/oops.ts(1,14): error TS2322: Type 'string' is not assignable to type 'number'.
src/oops.ts(3,24): error TS7006: Parameter 'x' implicitly has an 'any' type.
src/oops.ts(4,9): error TS6133: 'unused' is declared but its value is never read.
(終了コードは 1)
$ npx tsc -p tsconfig.app.json
(-b と同じ 3 件が出て、終了コードは 1)
npx tsc -b: ひな形のbuild("build": "tsc -b && vite build")が使う形です。参照先も型チェックしますnpx tsc -p tsconfig.app.json:src向けの設定を直接指定します
型チェックを手で流したいときは、この 2 つのどちらかを使います。TS7006 は strict(の中の noImplicitAny)から、TS6133 は noUnusedLocals から出ます。TS2322 は、strict と関係なく出ます。tsc -b が終わったあとに dist フォルダはできません。noEmit が true なので、書き出さないためです。
Next.js のひな形の tsconfig.json を読む
create-next-app 16.4.2 の既定の作り方(App Router・Tailwind CSS)で作ると、tsconfig.json は 1 つだけです。Vite のように分けていません。全文は次のとおりです(unpkg にある create-next-app 16.4.2 のひな形)。
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules"]
}
src フォルダを使う作り方では、paths の右側が "./src/*" になりました(手元の結果)。
| 項目 | 読み方 |
|---|---|
target | ES2017。Next.js のソースでは「勧める値」で、理由の文は「トップレベルの await のため」 |
allowJs | .js のファイルも、import して使えるようにする |
strict | 入るのは 5 系で、5 系の既定は false です。このひな形では、この行があるので strict が有効になります |
incremental | 前回のコンパイルの情報を .tsbuildinfo に残し、次を速くする。Next.js は 10.2.1 から、有効にすると型チェックを差分で行う |
plugins | エディタの中で動く言語サービスのプラグイン。{ "name": "next" } は Next.js の TypeScript プラグイン |
paths | @/ で始まる import を、プロジェクトの中の場所に読み替える(あとで説明) |
include | next-env.d.ts と、.ts・.tsx・.mts など。.next の中のパスは、この記事では意味を確かめていません |
lib | ブラウザの型(dom・dom.iterable)と esnext を入れる。値は Vite のひな形と違う。意味はあとで読む |
skipLibCheck・noEmit・jsx | Vite のひな形と同じ値。あとで読む |
esModuleInterop・module・moduleResolution・resolveJsonModule・isolatedModules | Next.js のソースが求める値(下で説明) |
next-env.d.ts は、Next.js が作り直すファイルです。手で直さず、.gitignore に入れます。tsconfig.json の include に入っている必要があり、create-next-app は自動で入れます(Next.js の文書より)。
Next.js が求める値と、理由
Next.js のソースによると(packages/next/src/lib/typescript/writeConfigurationDefaults.ts、16.4.2)、次の値は、「ユーザーが変えられない必須の値」(原文は "required and cannot be changed by the user")として扱われています。ソースを読んだ内容で、next dev や next build を流して確かめたものではありません。
| 項目 | 値 | ソースの理由の文 |
|---|---|---|
module | esnext | for dynamic import() support |
moduleResolution | bundler(TypeScript 5 以上で、module が commonjs・amd でないとき) | to match modern bundler resolution |
esModuleInterop | true | requirement for SWC / babel |
resolveJsonModule | true | to match webpack resolution |
isolatedModules | true(verbatimModuleSyntax が無いとき) | requirement for SWC / Babel |
jsx | react-jsx | next.js uses the React automatic runtime |
noEmit: true と target: ES2017 は、ソースでは「勧める値」です。noEmit には、理由の文がありません。Next.js の文書には、noEmit や moduleResolution: bundler を使う理由の説明が見つかりませんでした(2026年10月時点)。TypeScript の公式の手引きは、バンドラーを使うアプリに、module: esnext・moduleResolution: bundler・esModuleInterop: true を必須の設定として、noEmit: true を勧める設定として、挙げています。
Next.js の文書によると、既存のプロジェクトに TypeScript を足すときは、ファイルを .ts・.tsx にして next dev と next build を流すと、勧める設定の tsconfig.json ができます。ソースには、strict が無い tsconfig.json に false を書き足す処理もありますが、いつ呼ばれるかは確かめていません。ビルドの前に自分で tsc --noEmit を流して、型の誤りを見ることもできます(Next.js の文書)。
よく見る項目の意味(target・module・paths・strict ほか)
ここからは、2 つのひな形に共通して出てくる項目を、役割ごとに読みます。
既定値の読み方に注意があります。 TypeScript の公式の TSConfig Reference には、各項目に「Default:」の欄があります。2026年10月19日に開いた時点で、target・module・moduleResolution・esModuleInterop・rootDir・alwaysStrict の欄は、6.0 より前の値のまま残っていました。tsc のオプションのページ(Compiler Options)の既定も、同じく古いままです。たとえば target の欄は「ES5 otherwise」と書かれていますが、7.0.2 の既定は es2025 で、ES5 は選べません。この記事の既定値は、6.0・7.0 の公式の告知と、7.0.2 の tsc --help --all から取りました。Reference は、「その項目が何を決めるか」の説明だけに使っています。
出力の形を決める(target・module・lib・jsx)
| 項目 | 読み方 | 既定(TypeScript 7.0.2) |
|---|---|---|
target | どの JavaScript の書き方まで変換し(古い形に直し)、どれをそのまま残すか。ESNext は「その TypeScript が扱える最新の版」で、版によって意味が変わるので、公式は注意を促している。Vite は tsconfig の target を見ない | es2025。選べるのは es2015(es6)〜esnext |
module | プログラムのモジュールの方式。公式の目安は、「今の Node.js なら nodenext、バンドラーでまとめるコードなら preserve か esnext」 | esnext(6.0 から) |
lib | 組み込みの API(Math など)や、ブラウザのもの(document など)の型を、どれだけ入れるか。変える理由の例は、「ブラウザで動かさないので、dom の型は要らない」 | target に応じて決まる |
jsx | .tsx から出る JavaScript で、JSX をどう書き出すか。主な値は、react-jsx(本番向けの _jsx 呼び出し)・preserve(JSX をそのままにした .jsx)・react(React.createElement、古い方式)の 3 つ。7.0.2 では、ほかに react-native・react-jsxdev もあります | 決まった既定は無い(7.0.2 の help は undefined)。ひな形は 2 つとも react-jsx |
noEmit で書き出さないときも、module は要ります。型チェックとモジュールの探し方が、「出力するはずの形」で変わるためです。ESM と CommonJS の違いは、こちらの記事で説明しています。
import の探し方を決める(moduleResolution・paths・types・esModuleInterop)
moduleResolution
import の行から、実際のファイルを探すやり方を決めます。bundler はバンドラー向けで、package.json の imports・exports を読みますが、相対パスに拡張子を書かなくてよい値です。node16・nodenext は、今の Node.js 向けです。Vite の tsconfig.app.json は bundler、tsconfig.node.json は module: "nodenext" で、moduleResolution を書いていません。7.0.2 の --showConfig では "moduleResolution": "nodenext" と出ます。
7.0.2 で選べるのは、node16・nodenext・bundler の 3 つです。既定は、「module が nodenext なら nodenext、node16・node18 なら node16、それ以外は bundler」です。以前の値(node10・classic)が無くなった話は、TypeScript 7 の記事にあります。
paths: import の名前を読み替える
paths は、import の名前を、探す場所に読み替えます。@/lib/greet のような別名を作るときに使います。baseUrl があればそこからの相対、無ければ tsconfig ファイルからの相対です。
先ほどの tsconfig.paths.json(@/* を ./src/* に読み替える設定)で試します。src/lib/greet.ts と、それを読み込む src/usealias.ts がある場合です。
// src/lib/greet.ts
export const greet = (name: string) => `Hello, ${name}`;
// src/usealias.ts
import { greet } from "@/lib/greet";
export const message = greet("Vite");
paths が無い tsconfig.app.json で型チェックするとエラーになり、paths を足した設定では通ります(TypeScript 7.0.2・baseUrl なし)。
$ npx tsc -p tsconfig.app.json
src/usealias.ts(1,23): error TS2307: Cannot find module '@/lib/greet' or its corresponding type declarations.
$ npx tsc -p tsconfig.paths.json
(エラーなし)
paths は、tsc が書き出す import のパスを書き換えません。 公式は、paths は「別の道具が同じ読み替えを、実行のときやバンドルのときに行う」ことを TypeScript に伝えるためだけに使う、と書いています。Vite は、resolve.tsconfigPaths: true を指定したときだけ、paths を使います。Vite の文書は、速さに響くことと、TypeScript のチームがこの使い方を勧めていないことも書いています。vite build で動くかどうかは、この記事では確かめていません。
baseUrl は、7.0 で無くなりました。直し方は、TypeScript 7 の記事にあります。
types: グローバルに入れる型パッケージ
types の既定は [](何も入れない)です。6.0 から変わりました。5.9 までは、見える @types のパッケージを全部入れていました。types に書いたパッケージだけが、グローバルに入ります。書かないと、process(Node.js)や expect(Jest)のようなグローバルが使えず、自動 import の候補にも出ません。import して使うパッケージの型には、関係しません。
Vite のひな形は、tsconfig.app.json に "types": ["vite/client"]、tsconfig.node.json に "types": ["node"] を書いています。Vite の文書は、Vite の既定の型は Node.js の API 向けなので、ブラウザで動くコードには vite/client を足す、と説明しています。
esModuleInterop
CommonJS のパッケージを import x from "..." の形で読むときの、ずれを直す設定です。有効にすると allowSyntheticDefaultImports も有効になります。7.0 では false にできません。7.0.2 の help の既定は true です。
型チェックの厳しさを決める(strict)
strict は、たくさんの型チェックをまとめて有効にする設定です。中の仲間を 1 つずつ切ることもできます。主な仲間は 2 つです。
| 仲間の項目 | 読み方 |
|---|---|
noImplicitAny | 型が推論できず any になってしまうところを、エラーにする |
strictNullChecks | false だと、null と undefined が実質無視される |
strict の既定は true です(6.0 から。5.9 までは false)。strict の仲間の 1 つの alwaysStrict を除き、仲間の既定は「strict が false でなければ true」です(7.0.2 の help の言い方)。alwaysStrict は、7.0 では常に true です。公式は、今後の版で strict の中にチェックが増えることがあり、TypeScript を上げたときに新しい型エラーが出ることがある、と書いています。
前の「Vite のひな形」の例で、型を書いていない引数 x が TS7006 になりました。strict を切ると、そのエラーだけが消えます(TypeScript 7.0.2)。
$ npx tsc -p tsconfig.app.json --strict false
src/oops.ts(1,14): error TS2322: Type 'string' is not assignable to type 'number'.
src/oops.ts(4,9): error TS6133: 'unused' is declared but its value is never read.
Vite のひな形に strict の行が無くても、strict は有効です。--showConfig に strict が出なくても型チェックが厳しいことは、この例で確かめられます。
書き出すかどうかを決める(noEmit・skipLibCheck ほか)
| 項目 | 読み方 | 既定(TypeScript 7.0.2) |
|---|---|---|
noEmit | JavaScript・ソースマップ・型定義などを書き出さない。変換は Babel や swc などほかの道具に任せ、TypeScript は型チェックとエディタの支えに使う | false |
skipLibCheck | 型定義ファイル(.d.ts)の型チェックを飛ばす。速くなるが、型の正確さと引き換え。Vite の文書によると、Vite のひな形が true なのは、依存パッケージの型をチェックしないため | false |
2 つのひな形は、どちらも noEmit: true です。つまり、tsc は書き出さず、型チェックと、エディタの支えだけを担当します。変換とバンドルは、Vite や Next.js が行います。Vite の文書は、Vite は .ts を変換するだけで型チェックをしないので、本番のビルドでは Vite のビルドに加えて tsc --noEmit を流せる、と書いています。
allowImportingTsExtensions について、Reference には「noEmit か emitDeclarationOnly のときだけ」とあります。書き出した .js からは、.ts のパスが見つからないためです。7.0.2 のエラーの文には、rewriteRelativeImportExtensions も並びます。Vite のひな形で --noEmit false を付けると、次のエラーになります(TypeScript 7.0.2)。
$ npx tsc -p tsconfig.app.json --noEmit false
tsconfig.app.json(13,35): error TS5096: Option 'allowImportingTsExtensions' can only be used when one of 'noEmit', 'emitDeclarationOnly', or 'rewriteRelativeImportExtensions' is set.
よくある質問
tsconfig.json は、自分で全部書く必要がある?
必要ありません。compilerOptions は書かなくてもよく、書かなければコンパイラの既定値が使われます。Vite や Next.js は、ひな形を作る道具が書いてくれます。tsc --init でも、ひな形を作れます。
paths を書いたのに、import が見つからない?
paths は、TypeScript の型チェックに「この名前はここを指す」と伝える設定です。tsc は、書き出すコードの import を書き換えません。Vite は、resolve.tsconfigPaths: true を指定したときだけ、paths を使います。7.0 では baseUrl が無くなったので、paths の右側は、tsconfig.json からの相対パスで書きます。
TypeScript 6.0 や 5.9 でも、この記事のとおりに動く?
この記事の出力は、すべて TypeScript 7.0.2 のものです。6.0.3 と 5.9.3 では、同じ確かめをしていません。入っている版は、npx tsc --version で確かめてください。
まとめ
- tsconfig.json は、TypeScript のプロジェクトの設定ファイルで、対象のファイル(
files・include・exclude)と、コンパイラの設定(compilerOptions)を決めます。extendsで引き継ぎ、referencesで分けてつなぎます - Vite の
react-tsのひな形は、tsconfig を 3 つに分けています。根元のtsconfig.jsonは参照だけで、設定はtsconfig.app.json(src向け)とtsconfig.node.json(vite.config.ts向け)にあります。引数なしのnpx tscは、型の誤りがあっても何も出さず終了コード 0 で終わるので、npx tsc -bかnpx tsc -p tsconfig.app.jsonを使います - 2 つのひな形は、どちらも
noEmit: trueです。書き出しや変換は別の道具が行い、tscは型チェックを担当します - ひな形で入る TypeScript の版は違います(2026年10月19日時点で、create-vite 9.3.0 は 7.0.2、create-next-app 16.4.2 は 5.9.3)。
strictの既定は 6.0 からtrueです - TSConfig Reference の「Default:」の欄には、6.0 より前の値のままの項目があります。既定値は、告知と
tsc --help --allで確かめてください pathsはtscが書き出す import を書き換えません。baseUrlは 7.0 で無くなりました- この記事で確かめていないこと:
vite build・next dev・next buildの実行、TypeScript 6.0・5.9 での同じ確かめ、Windows と Linux。版が動く話なので、使う前に公式の最新の文書も見てください
参考資料
- TypeScript: tsconfig.json の概要(Handbook)
- TypeScript: TSConfig Reference
- TypeScript: Compiler Options(tsc のオプション)
- TypeScript: Project References
- TypeScript: Choosing Compiler Options
- Announcing TypeScript 6.0(公式ブログ)
- Announcing TypeScript 7.0(公式ブログ)
- Vite の文書: Features(TypeScript の扱い)
- Vite の Pull Request #15913(tsconfig を 3 つに分けた変更)
- Vite の Pull Request #22110(TypeScript 6 に上げた変更)
- create-vite の react-ts ひな形
- Next.js の文書: TypeScript
- Next.js のソース: writeConfigurationDefaults.ts(16.4.2)
- create-next-app 16.4.2 のひな形の tsconfig.json
※この記事は、公式の資料をもとに AI(Claude)で下書きし、2026年10月19日時点の公式の資料と照らして確かめてから公開しています。誤りに気づいたらお問い合わせからお知らせください。



