tsconfig.json とは?書き方と、よく見る項目の読み方(Vite・Next.js のひな形で)

PR
tsconfig.json とは?書き方と、よく見る項目の読み方(Vite・Next.js のひな形で)
この記事は約31分で読めます。

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 があれば []、無ければ **/*(すべて)
excludeinclude で見つけたものから外す

拡張子もワイルドカードも無い最後の部分は、フォルダとみなされ、その中の .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.jsonsrc の中のコード(ブラウザで動くアプリ)lib は ["ES2023", "DOM"]、types は ["vite/client"]、moduleResolution は "bundler"、jsx は "react-jsx"。include は ["src"]
tsconfig.node.jsonvite.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同じく、あとで読む
allowImportingTsExtensionsimport に .ts・.tsx を書けるようにする。noEmit のときなどに使える(あとで説明)
verbatimModuleSyntax型だけの印(type)が付いていない import・export を、変換も省略もしない
allowArbitraryExtensionsTypeScript の手引きが、バンドラーを使うアプリで勧めている項目のひとつ
moduleDetectionこの記事では意味を確かめていないので、説明しません

「Linting」の 4 つは、コードの書き方の決まりです。

項目読み方
noUnusedLocals使っていない変数をエラーにする
noUnusedParameters使っていない引数をエラーにする。_ で始まる名前は除く
erasableSyntaxOnly消すだけで JavaScript になる書き方だけに絞る。Node.js は 23.6 から TypeScript のファイルを直接動かせますが、その形だけが対象です
noFallthroughCasesInSwitchswitch の 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/*" になりました(手元の結果)。

項目読み方
targetES2017。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 を、プロジェクトの中の場所に読み替える(あとで説明)
includenext-env.d.ts と、.ts・.tsx・.mts など。.next の中のパスは、この記事では意味を確かめていません
libブラウザの型(dom・dom.iterable)と esnext を入れる。値は Vite のひな形と違う。意味はあとで読む
skipLibCheck・noEmit・jsxVite のひな形と同じ値。あとで読む
esModuleInterop・module・moduleResolution・resolveJsonModule・isolatedModulesNext.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 を流して確かめたものではありません。

項目値ソースの理由の文
moduleesnextfor dynamic import() support
moduleResolutionbundler(TypeScript 5 以上で、module が commonjs・amd でないとき)to match modern bundler resolution
esModuleInteroptruerequirement for SWC / babel
resolveJsonModuletrueto match webpack resolution
isolatedModulestrue(verbatimModuleSyntax が無いとき)requirement for SWC / Babel
jsxreact-jsxnext.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 になってしまうところを、エラーにする
strictNullChecksfalse だと、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)
noEmitJavaScript・ソースマップ・型定義などを書き出さない。変換は 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。版が動く話なので、使う前に公式の最新の文書も見てください

参考資料

※この記事は、公式の資料をもとに AI(Claude)で下書きし、2026年10月19日時点の公式の資料と照らして確かめてから公開しています。誤りに気づいたらお問い合わせからお知らせください。

PR
PR
タイトルとURLをコピーしました