TypeScript 6.0 — JSベース最後のリリースが変えるデフォルトの景色

TypeScriptTypeScript 6.0tsgoTemporal APIECMAScriptマイグレーション

TypeScript 6.0が2026年3月23日にリリースされました(2026年3月23日 TypeScript Blog)。型安全性の観点から言うと、このリリースは「新機能の追加」よりも「デフォルトの正常化」に重心があります。

公式ブログの冒頭にはこう書かれています。

TypeScript 6.0 is a unique release in that it is intended to be the last release based on the current JavaScript codebase. The team is working on a new codebase for the TypeScript compiler and language service written in Go that takes advantage of the speed of native code and shared-memory multi-threading, which will be the foundation of TypeScript 7.0 and beyond.

TypeScript 6.0はJavaScriptで書かれた現行コンパイラの最終リリースです。次のTypeScript 7.0はGoで書き直されたネイティブコンパイラ(tsgo)がベースになります。つまり6.0は5.x系と7.0の間を繋ぐ「橋渡し」のリリースであり、そこに含まれる変更の多くは7.0への準備として設計されています。

デフォルト値の大転換

TypeScript 6.0の最大のインパクトは、新機能ではなくデフォルト値の変更です。長年「推奨はされているけど自分で有効にする必要があった」設定が、ようやくデフォルトになりました。

オプション5.x以前のデフォルト6.0のデフォルト
strictfalsetrue
modulecommonjsesnext
targetes2020es2025
types@typesパッケージを自動検出[](空配列)
rootDirソースファイルから推論tsconfig.jsonのディレクトリ

strict: trueがデフォルトになったのは、個人的にずっと待っていた変更です。TypeScriptを始めたばかりの人がstrict: falseのまま書いて、後からstrictに移行しようとして大量のエラーに絶望する、というパターンは本当によく見かけました。最初からstrictで始められるようになるのは、エコシステム全体の型安全性の底上げになると思います。

types: []のデフォルト化も大きいです。これまではnode_modules/@types配下のパッケージが全て自動で読み込まれていましたが、これは意図しないグローバル型の汚染や、ビルドパフォーマンスの低下を招いていました。6.0からは必要な型定義を明示的に指定する方式に変わっています。

自分の環境で試してみました

実際にTypeScript 6.0 RCをインストールして、変更点を確認してみました。

  • Node.js: v20.19.5
  • TypeScript: 6.0.1-rc(npm install -D typescript@rc
  • tsgo: 7.0.0-dev.20260330.1(npm install -D @typescript/native-preview

tsc --initの出力

tsc --initで生成されるtsconfig.jsonを確認すると、新しいデフォルト値が反映されています。

{
  "compilerOptions": {
    "module": "nodenext",
    "target": "esnext",
    "types": [],
    "strict": true,
    "sourceMap": true,
    "declaration": true,
    "declarationMap": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "jsx": "react-jsx",
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "noUncheckedSideEffectImports": true,
    "moduleDetection": "force",
    "skipLibCheck": true
  }
}

strict: trueが明示的に含まれ、noUncheckedIndexedAccessexactOptionalPropertyTypesまで推奨設定として生成されます。新規プロジェクトの型安全性がぐっと上がる構成です。

廃止されたオプションを指定するとどうなるか

--target es5を指定してみます。

$ npx tsc --ignoreConfig --target es5 test.ts

error TS5107: Option 'target=ES5' is deprecated and will stop functioning
in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"'
to silence this error.

即座にエラーになります。--module amd--moduleResolution classicも同様です。

$ npx tsc --ignoreConfig --module amd test.ts

error TS5107: Option 'module=AMD' is deprecated and will stop functioning
in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"'
to silence this error.
$ npx tsc --ignoreConfig --moduleResolution classic test.ts

error TS5107: Option 'moduleResolution=classic' is deprecated and will stop
functioning in TypeScript 7.0. Specify compilerOption
'"ignoreDeprecations": "6.0"' to silence this error.

エラーメッセージの通り、"ignoreDeprecations": "6.0"をtsconfig.jsonに追加すれば一時的に抑制できますが、TypeScript 7.0ではこのエスケープハッチも使えなくなります。

tscにファイル引数を渡す挙動の変化

6.0では、tsconfig.jsonが存在するディレクトリでtsc file.tsのようにファイルを直接指定するとエラーになります。

$ npx tsc test.ts

error TS5112: tsconfig.json is present but will not be loaded if files are
specified on commandline. Use '--ignoreConfig' to skip this error.

これまでは、ファイルを指定するとtsconfig.jsonが暗黙的に無視されていましたが、この挙動は混乱の元でした。6.0からは明示的に--ignoreConfigを付けるか、tsconfig.jsonの設定に従ってtscを引数なしで実行するか、どちらかを選ぶ必要があります。

削除・非推奨になったオプション

6.0の変更の多くは「既に使われるべきではなかったオプションの整理」です。

完全に削除されたもの

  • --outFile — 複数ファイルを1つにバンドルする機能。外部バンドラー(webpack, Vite, esbuild等)の利用が推奨されます
  • module: amd / umd / systemjs / none — レガシーなモジュールシステム
  • --moduleResolution classic — 古いモジュール解決アルゴリズム
  • moduleキーワードによる名前空間宣言namespaceキーワードに統一
  • assert構文(Import Assertions)withキーワード(Import Attributes)に置き換え

非推奨("ignoreDeprecations": "6.0"で一時的に抑制可能)

  • --target es5 — 最低ターゲットはES2015に。ES5出力が必要な場合は外部コンパイラで後処理する方式が推奨されます
  • --downlevelIteration — ES5ターゲットの廃止に伴い不要に
  • --moduleResolution nodenodenextまたはbundlerへの移行が必要
  • --baseUrl — パスのプレフィックスはpathsエントリに統合
  • --esModuleInterop false--allowSyntheticDefaultImports false — falseに設定することが非推奨に

型安全性の観点から言うと、esModuleInterop: falseを非推奨にしたのは正しい判断だと思います。import * as express from "express"と書かなければならないのは、実行時のモジュール挙動と型システムの間のズレが原因でした。6.0以降はimport express from "express"と自然に書けるのがデフォルトになります。

新機能

デフォルト値の変更に隠れがちですが、新機能もいくつか入っています。

Temporal APIの型サポート

ECMAScript 2025に含まれるTemporal APIの型定義が組み込まれました。--lib esnextまたはesnext.temporalを指定すると使えます。

const now = Temporal.Now.instant();
const yesterday = now.subtract({ hours: 24 });
const tomorrow = now.add({ hours: 24 });

console.log(`Now:       ${now}`);
console.log(`Yesterday: ${yesterday}`);
console.log(`Tomorrow:  ${tomorrow}`);

const today = Temporal.Now.plainDateISO();
const nextWeek = today.add({ days: 7 });
console.log(`Today:     ${today}`);
console.log(`Next week: ${nextWeek}`);

自分の環境でTypeScript 6.0 RCの型チェックを通してみたところ、問題なくコンパイルできました。Temporal.Now.instant()Temporal.Now.plainDateISO()の返り値に対して.add().subtract()の補完もきちんと効きます。

ただし、ランタイムのサポート状況はまだ限定的です。

Temporal APIのブラウザ対応状況

現時点でのブラウザ対応状況は以下の通りです(Can I Use)。

ブラウザ対応状況
Chrome144+(2026年1月〜)
Firefox139+(2025年5月〜)
SafariTechnology Previewで部分対応(一部フラグ付き)
EdgeChrome同様144+で対応

SafariのフルサポートがまだなのでBaselineには到達していません。Node.jsでの利用もランタイムバージョン次第です。クロスブラウザで使いたい場合は@js-temporal/polyfilltemporal-polyfillのライブラリを併用する形になると思います。

Map/WeakMapのupsertメソッド

getOrInsert()getOrInsertComputed()が追加されました。「キーが存在しなければデフォルト値を入れて返す」というよくあるパターンを1行で書けるようになります。

const cache = new Map<string, number[]>();

// Before: 冗長なパターン
// if (!cache.has("users")) { cache.set("users", []); }
// cache.get("users")!.push(1);

// After: getOrInsert
const values = cache.getOrInsert("users", []);
values.push(1);
values.push(2);

console.log(cache.get("users")); // [1, 2]

// getOrInsertComputed: 高コストな初期化を遅延実行
const expensiveCache = new Map<string, object>();
const result = expensiveCache.getOrInsertComputed("config", (key) => {
  console.log(`Computing value for ${key}...`);
  return { loaded: true };
});

型安全性の観点から言うと、cache.get("users")!.push(1)!(non-null assertion)を使わなくて済むのが大きいです。getOrInsertの返り値は必ず存在する値なので、!による型の穴がなくなります。

自分の環境でこのコードを型チェックしたところ、問題なくコンパイルが通りました。

RegExp.escape()

ES2025のStage 4プロポーザルであるRegExp.escape()の型定義が追加されています。ユーザー入力を正規表現に組み込む際のエスケープが安全にできるようになります。

const userInput = "hello.world (test) [brackets] {curly} $100";
const escaped = RegExp.escape(userInput);
const regex = new RegExp(escaped);

console.log(regex.test(userInput)); // true

こちらも型チェックは問題なく通りました。

DOMライブラリの統合

これまではdom.iterabledom.asynciterableを別途指定する必要がありましたが、6.0からはdomライブラリに統合されました。NodeListHTMLCollectionのfor-ofループが追加設定なしで型チェックを通るようになります。

TypeScript 7.0(tsgo)との比較

せっかくなので、tsgoもインストールして同じプロジェクトでビルド時間を比較してみました。

$ time npx tsc
npx tsc  2.24s user 0.11s system 199% cpu 1.179 total

$ time npx tsgo
npx tsgo  0.46s user 0.10s system 126% cpu 0.442 total

テストファイル数が少ないので劇的な差にはなっていませんが、それでもtsgoの方が約2.7倍速い結果になりました。大規模プロジェクトでは公式ベンチマークで10倍以上の差が出ているとのことです(2025年12月 TypeScript Blog)。

Compile time improvements of 10x have been seen for large code bases, and the time to load projects has decreased approximately 8x.

tsgoは@typescript/native-previewパッケージで今すぐ試せます。tscと並行して動かせるので、自分のプロジェクトでどの程度の速度差が出るか確認してみるのも良いと思います。

TypeScript 6.0には--stableTypeOrderingフラグも追加されており、tsgoとの型順序の違いを事前に検出できます。ただし最大25%程度の型チェック速度低下があるため、CIで定期的に確認する用途が現実的だと思います。

マイグレーション

最低限やること

ほとんどのプロジェクトで以下の対応が必要になるはずです。

1. typesを明示的に指定する

{
  "compilerOptions": {
    "types": ["node"]
  }
}

Jestを使っている場合は"types": ["node", "jest"]のように、必要な型定義を列挙します。

2. rootDirを確認する

ソースファイルがtsconfig.jsonより深い階層(例: src/配下)にある場合は、明示的に指定が必要です。

{
  "compilerOptions": {
    "rootDir": "./src"
  }
}

設定しないと、出力ディレクトリの構造が意図しない形になることがあります。

3. Import構文の更新

esModuleInterop: falseで書いていた名前空間インポートを、デフォルトインポートに書き換えます。

// Before
import * as express from "express";

// After
import express from "express";

4. baseUrlの移行

baseUrlを使っていた場合は、そのプレフィックスをpathsエントリに統合します。コミュニティ製の自動移行ツールts-fix-baseurlGitHub)も利用できます。

段階的な移行

一度に全てを対応するのが難しい場合は、tsconfig.jsonに以下を追加すれば非推奨警告を一時的に抑制できます。

{
  "compilerOptions": {
    "ignoreDeprecations": "6.0"
  }
}

ただし、これはTypeScript 7.0では機能しなくなります。7.0のリリースまでに段階的に対応を進めるのが良いと思います。

公式のマイグレーションガイドもGitHub Issueで公開されています(GitHub - TypeScript 6.0 Migration Guide)。

まとめるとこういうリリース

TypeScript 6.0は、派手な新機能を追加するリリースではありません。「モダンなJavaScript/TypeScript開発ではこうあるべき」というデフォルトを、10年分まとめて正しく設定し直したリリースです。

  • strictがデフォルトになり、新規プロジェクトの型安全性が底上げされます
  • ES5やAMD/UMDの廃止で、レガシーなターゲットとの決別が明確になりました
  • Temporal APIやMap.getOrInsertなど、ECMAScript 2025の型サポートも入っています
  • そして何より、これがJSベース最後のリリースです

次のTypeScript 7.0は、Goで書き直されたコンパイラで10倍速くなる世界がやってきます。6.0での非推奨オプションの整理は、その新しいコンパイラが余計なレガシーコードを抱えずに済むための準備でもあります。

マイグレーションの手間はありますが、"ignoreDeprecations": "6.0"で段階的に進められます。まずは自分のプロジェクトでnpm install -D typescript@rcしてみて、どのくらいのエラーが出るか確認してみるのが良いと思います。