一般社団法人 全国個人事業主支援協会

COLUMN コラム

  • TypeScript 5.x の新機能を徹底解説:型安全なコードを書くために

TypeScript 5.x系の進化を振り返る

TypeScriptは近年、メジャーバージョンのアップデートを重ねるごとに、型システムの表現力とデベロッパーエクスペリエンスを大幅に向上させてきましました。筆者は大規模なフロントエンド・バックエンドプロジェクトでTypeScriptを3年以上使い続けていますが、5.x系のリリースは特に実務でのインパクトが大きいと感じています。

本記事では、TypeScript 5.0から5.5までの主要な新機能を実践的な視点で解説します。単なる機能紹介ではなく、実際のプロジェクトでどう活かすかに焦点を当てます。

デコレータの正式サポート(5.0)

TypeScript 5.0では、ECMAScript Decorators提案(Stage 3)に準拠したデコレータが正式にサポートされましました。従来の実験的デコレータ(experimentalDecorators)とは異なる新しい仕様です。

function logged(
target: any,
context: ClassMethodDecoratorContext
) {
const methodName = String(context.name);
function replacementMethod(this: any, ...args: any[]) {
console.log(`[LOG] ${methodName} called with:`, args);
const result = target.call(this, ...args);
console.log(`[LOG] ${methodName} returned:`, result);
return result;
}
return replacementMethod;
}

class UserService {
@logged
findUser(id: number): string {
return `User_${id}`;
}
}

const service = new UserService();
service.findUser(42);
// [LOG] findUser called with: [42]
// [LOG] findUser returned: User_42

新しいデコレータはClassMethodDecoratorContextなどの型付きコンテキストを受け取ります。これにより、型安全なデコレータの実装が可能になりましました。NestJSなどのフレームワークを使っている方は、今後の移行を意識しておくとよいでしょう。

constタイプパラメータ(5.0)

const修飾子をジェネリクスに付与できるようになりましました。これにより、リテラル型の推論がより厳密になります。

// constなしの場合
function withoutConst(args: T): T {
return args;
}
const a = withoutConst(['hello', 'world'] as const);
// readonly ["hello", "world"]

// constありの場合(5.0新機能)
function withConst(args: T): T {
return args;
}
const b = withConst(['hello', 'world']);
// readonly ["hello", "world"] — as constなしでリテラル型推論

API定義やルーティングテーブルなど、リテラル型を保持したい場面で非常に便利です。

型の絞り込み強化(5.1〜5.3)

TypeScript 5.1以降、関数の戻り値におけるundefinedの扱いが改善されましました。また、5.3ではswitch文での型ガードが強化されています。

// 5.1: undefinedを返す関数の型推論改善
function greet(): undefined {
// return文なしでもOK(以前はreturn undefined;が必要だった)
}

// 5.3: switch(true)パターンでの型絞り込み
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'rect'; width: number; height: number };

function area(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'rect':
return shape.width * shape.height;
}
}

インポート属性のサポート(5.3)

ECMAScriptのImport Attributes提案に対応し、with構文でインポートにメタ情報を付与できるようになりましました。

import config from './config.json' with { type: 'json' };
console.log(config.apiUrl);

JSONモジュールのインポートが型安全に行えるため、設定ファイルの読み込みがスマートになります。

推論の改善とNoInfer(5.4)

TypeScript 5.4ではNoInferユーティリティ型が導入されましました。これはジェネリクスの型推論を制御する強力なツールです。

// NoInferなしの場合
function createFSM(
initial: S,
states: S[]
): void { }

// 'idle' | 'loading' | 'typo' と推論される
createFSM('typo', ['idle', 'loading']);

// NoInferありの場合(5.4)
function createFSMSafe(
initial: NoInfer,
states: S[]
): void { }

// エラー: 'typo'は'idle' | 'loading'に含まれない
// createFSMSafe('typo', ['idle', 'loading']);
createFSMSafe('idle', ['idle', 'loading']); // OK

この機能は、意図しない型の拡張を防ぎたい場面で絶大な効果を発揮します。状態管理やイベントシステムの設計で特に重宝するでしょう。

型述語の推論(5.5)

TypeScript 5.5では、関数が型ガードとして機能する場合に、コンパイラが自動的に型述語を推論するようになりましました。

// 以前は明示的な型述語が必要だった
// function isString(x: unknown): x is string { ... }

// 5.5: 自動推論される
const values: (string | number)[] = ['a', 1, 'b', 2];
const strings = values.filter((v): v is string => typeof v === 'string');
// strings: string[]

// 正規表現による型絞り込みも改善
function process(input: string | null) {
if (typeof input === 'string' && /^\d+$/.test(input)) {
// inputはstring型として扱われる
const num = parseInt(input, 10);
}
}

パフォーマンスの改善

TypeScript 5.x系では、型チェックのパフォーマンスも継続的に改善されています。

  • 5.0:モジュール解決のキャッシュ改善により、大規模プロジェクトでのビルド時間が約10〜20%短縮
  • 5.1:宣言ファイル生成の最適化
  • 5.3tsconfig.jsonskipLibCheck使用時の改善
  • 5.4:型インスタンス化の制限緩和とメモリ使用量の削減
  • 5.5:プロジェクト参照を使ったモノレポ構成でのインクリメンタルビルドの高速化

筆者のプロジェクト(約500ファイル)では、5.0から5.5への更新で型チェック時間が約15%短縮されましました。

移行時の注意点と実践的なアドバイス

新バージョンへの移行にはいくつか気をつけるべき点があります。

  • 実験的デコレータとの互換性:新旧デコレータは共存できないため、使用するライブラリの対応状況を確認する
  • strictモードの強化:新しい型チェックが追加されるため、更新後にエラーが増える可能性があります
  • 段階的な更新:マイナーバージョンごとに更新・テストするのが安全なアプローチ
  • エディタの対応:VS Codeは最新のTypeScriptバージョンに素早く対応するが、他のIDEは遅れる場合があります

まとめ

TypeScript 5.x系は、型安全性の向上、開発体験の改善、パフォーマンスの最適化が三位一体で進化しています。特にNoInfer、型述語の自動推論、新デコレータは実務での影響が大きい機能です。プロジェクトの規模に関わらず、最新バージョンへの追従は大きなメリットがあります。まずは新しいプロジェクトから5.x系を導入し、既存プロジェクトは段階的に移行していくことをお勧めします。

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア