7月27日、マイクロソフトはTypeScript 5.6のベータ版を発表した。この新バージョンは、多くの新機能と改善をもたらし、開発者にとってさらに使いやすいものとなっている。以下は、主要な新機能と改善点の概要である。
本記事は、以下のエキスパートに監修していただきました:
うひょさん(株式会社カオナビ フロントエンドエンジニア)
主な新機能
null及び真偽値チェックの厳格化
TypeScriptには、常に特定の評価結果になる真偽値チェックをエラーとして扱う機能がある。TS 5.6ではチェックの範囲が拡大してより多くのミスを検出できるようになった。
これにより、多くのバグを事前に防ぐことができる。例えば、正規表現を誤って条件式に直接使用した場合や、比較演算子の優先順位を誤って解釈した場合など、以下のようなコードがエラーとなる。
if (/0x[0-9a-f]/) {
// 以前は常に真となるこのようなコードが許容されていたが、
// TypeScript 5.6ではエラーとなる。
}
if (x => 0) {
// エラー: この表現は常に真である。
}
function isValid(value: string | number, options: any, strictness: "strict" | "loose") {
if (strictness === "loose") {
value = +value;
}
return value < options.max ?? 100;
// エラー: ??の右オペランドには到達できません。左オペランドがnullishになることがありません
}
Iteratorヘルパーメソッド
イテレータ(iterator)とは、データ構造を順番に走査するためのオブジェクトである。イテレータは、コレクション(例えば配列やセット)の各要素に順番にアクセスするための標準的な方法を提供する。
イテレータは以下のメソッドを実装している。
next()
メソッド: 次の要素を返す。このメソッドは、次の値とコレクションが終了したかどうかを示す真偽値を持つオブジェクトを返す。[Symbol.iterator]()
メソッド: イテレータ自身を返す。これにより、オブジェクトが反復可能(iterable)であることを示す。
しかしこれまでIteratorは、Arrayが持つ多くのメソッドを直接利用することはできず、それらのメソッドを利用するには、Array.from()などを用いてArrayに変換する必要があった。しかしECMAScript仕様では、イテレータにArrayが持つメソッドを追加する提案が行われており、TypeScriptもそれに追従することとなった。これにより、配列のmap
やfilter
のようなメソッドを利用できるようになった。
以下は、生成されたイテレータに対してmap
メソッドやtake
メソッドを使用して動作させる例である。
function* positiveIntegers() {
let i = 0;
while (true) {
yield i++;
}
}
const evenNumbers = positiveIntegers().map(x => x * 2);
for (const value of evenNumbers.take(5)) {
console.log(value); // 0, 2, 4, 6, 8
}
また、MapやSetのkeys()
, values()
, entries()
といったメソッドはイテレーターを返すメソッドだが、それらに対してもArrayのメソッドを利用できるようになった。以下の例では、Map
オブジェクトのキーと値を反転させて新しいMap
を作成している。
function invertKeysAndValues<K, V>(map: Map<K, V>): Map<V, K> {
return new Map(
// map.entries()の戻り値はIterator
map.entries().map(([k, v]) => [v, k])
);
}
さらに、新しいIterator
オブジェクトを拡張して、独自のイテレータを作成することも可能である。
/**
* 無限に0を生成するイテレータ
*/
class Zeroes extends Iterator<number> {
next() {
return { value: 0, done: false } as const;
}
}
const zeroes = new Zeroes();
// 無限に1を生成するように変換する
const ones = zeroes.map(x => x + 1);
既存のIterable
やIterator
を新しい型に適応させるためのIterator.from
も使用できる。
Iterator.from(...).filter(someFunction);
任意のモジュール識別子のサポート
JavaScriptモジュールからバインディングをエクスポートするとき、識別子としては無効な名前でも、文字列リテラルで名前を指定してエクスポートできるようになった。これにより、他言語との相互運用性が向上し、コードを生成するツールにとっても有用である。
const banana = "🍌";
export { banana as "🍌" };
import { "🍌" as banana } from "./foo";
--noUncheckedSideEffectImports
オプション
サイドエフェクトインポートに対するチェックを強化し、モジュールが見つからない場合にエラーを出力するようになった。これにより、タイプミスによるインポートエラーを早期に発見できる。
import "non-existent-module";
// エラー: モジュールが見つからない
--noCheck
オプション
型チェックをスキップしてファイルを生成するオプションが追加された。これにより、ビルド時間の大幅な短縮が可能になった。
// 型チェックをスキップしてファイルを生成する例
tsc --noCheck
このオプションは、--isolatedDeclarationsと組み合わせて使用することで、型宣言ファイル(d.ts)を生成する際にも役立つ(isolatedDeclarationsに関する既報はこちら)。例えば、プロジェクトが--isolatedDeclarationsを使用している場合、--noCheckを指定することで、型チェックを行わずに宣言ファイルを生成することができる。
なお、--noCheckを指定してもプロジェクトが--isolatedDeclarationsを使用していない場合、TypeScriptは.d.tsファイルを生成するために可能な限り型チェックを行う。この場合、完全な型チェックよりも迅速に生成されるが、依然として一定の型チェックが行われる。
中間エラーを含む--build
の許可
プロジェクトの依存関係にエラーがあってもビルドを続行できるようになった。これにより、段階的なアップグレードが容易になった。従来は、依存関係にエラーがあるとビルドが停止していたが、この変更により、エラーを含むプロジェクトでもビルドを続行し、可能な限り出力ファイルを生成できるようになった。
詳細はAnnouncing TypeScript 5.6 Betaを参照していただきたい。