8月2日、TypeScript 5.9がリリースされた。

この記事では、TypeScript 5.9 の新機能と、バージョン6以降のロードマップについて簡単に紹介する。詳しくは[リリースノート(英語)](https://devblogs.microsoft.com/typescript/announcing-typescript-5-9/を参照していただきたい。
本記事は、以下のエキスパートに監修していただきました:
監修者からのコメント:
TypeScript 5.9は、従来の3ヶ月に1回のリリースサイクルから外れた約5ヶ月ぶりのリリースとなりました。本記事末尾にもあるように、ネイティブ化されたTypeScript 7.0に向けた準備にリソースが注がれているのでしょう。
次のTypeScript 6.0がいつリリースされるのかは不透明です。TypeScriptはセマンティックバージョニングではなく、これまでの4.0や5.0といったリリースは特別なものではありませんでした。しかし、6.0は、将来に備えたdeprecationなどが追加されることが予告されており、すこし特別なリリースとなりそうです。それでも、大きな破壊的変更などは無さそうなのであまり心配しなくてもよいでしょう。
TS 5.9の変更の中では、まだプレビューですが展開可能なホバー機能が目を引きます。型のデバッグをする人には嬉しい機能となるでしょう。
また、Zodなど型チェックに時間がかかるライブラリを使っている場合はパフォーマンス改善の恩恵を受けられるかもしれません。ぜひ試してみましょう。
生成される tsconfig.json がスリムに
長らく tsc --init は数百行に及ぶコメント付き tsconfig.json を吐き出していたが、5.9 では実践的な最小構成が採用された。モジュール解決は module: "nodenext"、ターゲットは esnext、さらに strict: true や jsx: "react-jsx" といった実践的な設定がデフォルトで有効になっている。 生成ファイルは次のようにおよそ 40 行に収まり、 コメントも最小限となっている。
{
  // Visit https://aka.ms/tsconfig to read more about this file
  "compilerOptions": {
    "module": "nodenext",
    "target": "esnext",
    "types": [],
    "sourceMap": true,
    "declaration": true,
    "declarationMap": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "strict": true,
    "jsx": "react-jsx",
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "noUncheckedSideEffectImports": true,
    "moduleDetection": "force",
    "skipLibCheck": true
  }
}
開発者はファイルを開いた瞬間に「どこを編集すればよいか」が把握でき、残りのオプションはエディタ補完や公式リファレンスで確認する、というワークフローを想定している。
import defer――モジュール評価を必要な瞬間まで遅延
TypeScriptでは、ECMAScriptで提案されている「Deferred Module Evaluation」を取り込んだ。次のような書式でモジュール評価を遅延できる。
import defer * as feature from "./some-feature.js";
// ここでは副作用が発生しない
...
console.log(feature.specialConstant); // 初アクセス時に初期化が実行される
import defer は依存モジュールをロードだけしておき、最初のプロパティアクセス時に初めて実行する。初期化処理を必要なときまで遅延させることができるため、起動コストを節約することができる。
ただし import defer については、TypeScriptではあくまで構文に対応しただけであり、実際の恩恵を受けるには import defer に対応したランタイム(またはバンドラ)が必要とされる。
Node.js 20 に合わせた --module node20
TypeScript では、--module と --moduleResolution に対して複数の node* オプションが用意されている。最新の変更では、--module nodenext が CommonJS モジュールから ECMAScript モジュールを require() できるようにする一方、標準仕様に沿った import attributes を優先するため、以前のNode.jsで利用可能だった import assertions を正しく拒否するようになった。
一方 5.9 で追加された --module node20 は Node.js v20 時点の仕様を固定的に再現し、暗黙の --target es2023 とともに安定したビルド結果を保証する。「最新を試すより、現行 LTS と同じ挙動で動かしたい」という保守的なポリシーのプロジェクトに向いたオプションだ。
エディタ体験の改善
DOM APIに簡単なコメントが表示されるように
これまでリファレンス URL のみだった DOM API に、MDN 由来の短い説明が付与されるようになった。型をホバーした瞬間に概要が読めるようになり、開発者にとっての利便性が向上する。展開可能なホバー(プレビュー)
VS Code など LSP 対応エディタで、ツールチップ左端に現れる「+」「-」アイコンをクリックすると型を段階的に展開できる。深いジェネリック型を追う際に定義ジャンプが不要になる。ホバー長の上限を設定値で変更
js/ts.hover.maximumLengthにより、ツールチップ内の文章が省略表示される文字数を制御可能になった。既定値も拡大され、5.9 ではより多くの情報が一目で確認できる。
ビルド時のパフォーマンスを改善
型パラメータ展開の結果をキャッシュすることで、複雑な型の計算を擁するライブラリ(例えばZodやtRPCなど)を使用する際のビルド時間とメモリ消費が抑制された。その他の内部的な処理の最適化と合わせて、プロジェクト全体で最大一割程度の速度向上が報告されている。
一方、lib.d.ts の更新によって ArrayBuffer と各種 TypedArray の関係が見直され、Buffer 互換コードなどで新たな型エラーが生じる可能性がある。@types/node の更新や、Uint8Array.buffer への明示変換で多くは解決できるとされている。
TypeScript 6.0、そして7.0に向けて
TypeScript 7.0は、Go言語によって書き直され、10倍高速化すると言われており、TypeScriptの歴史上でも大きな転換点となると見なされている。
一方次期リリースであるTypeScript 6.0 は、TypeScript 7.0への移行をスムーズに行えるようにするための準備的なリリースとなる予定だ。ほとんどのプロジェクトで TypeScript 6.0 へのアップグレードに大きな問題は発生せず、TypeScript 5.9 との API 互換性も完全に確保される見込みとされている。そのため、来るTypeScript 7.0に備えて、5.9以降もこまめにバージョンアップに追随していくことが望ましいと言えるだろう。
詳細はAnnouncing TypeScript 5.9を参照していただきたい。