編集

TypeScript 5.2

TypeScript 5.2 がリリース。

#Explicit Resource Management

ECMAScript Stage 3 proposal の Explicit Resource Management が先行実装されました。

https://github.com/tc39/proposal-explicit-resource-management

#Explicit Resource Management のメリット

  • リソース (メモリ、I/O など)の明示的な解放
  • try-finally などを利用した場合と比べて、安全で実装が容易なリソース管理
  • リソースを扱う API のインターフェース統一
    • NodeJS API では、http.Server は close、stream.Readable は destroy などリソースを解放するメソッドに統一感がない

#using 宣言と Symbol.dispose メソッド

using宣言は、何らかの理由でスコープを脱出する際に Symbol.dispose メソッドを実行します。Python の with 文や Java の try-with-resources 文、C#の using 宣言に似ています。

tsx
const getResource = (label: string) => {
	return {
		[Symbol.dispose]: {
			console.log(`Disposed ${label}!`)
		}
	}
}

{
	using resource = getResource("fish")
} // Disposed fish!

using 宣言のクリーンアップはスタックのように振る舞います。

tsx
const race = () => {
  using turtle = getResource("turtle");
  using rabbit = getResource("rabbit");
};
race();
// Dispose rabbit!
// Dispose turtle!

#await using 宣言とSymbol.asyncDispose メソッド

クリーンアップ関数が非同期の場合は、Symbol.asyncDispose を利用します。

tsx
const getResource = (label: string) => {
	return {
		async [Symbol.asyncDispose]: {
			await sleep(1000);
			console.log(`Disposed ${label}!`)
		}
	}
}

{
	await using resource = getResource("fish")
} // Disposed fish!

#DisposableStack と defer()メソッド

DisposableStack と defer を利用すれば、Symbol.dispose を登録することなくコールバックを登録することが出来ます。Go 言語などの defer をイメージしてもいいですし、Symbol.dispose の場合と同様に振る舞います。

tsx
using cleanup = new DisposableStack();
cleanup.defer(() => {
  console.log("Cleanup!");
});

非同期なクリーンアップ関数を実行する場合は、DisposableStack の代わりに AsyncDisposableStack を利用します。

tsx
await using stack = new AsyncDisposableStack();
stack.defer(async () => {
  await someAsyncCleanupOperaiton();
});

#Explicit Resource Management を利用する

利用したい場合は、"esnext.disposable"を lib に設定する必要があります。

json
{
  "compilerOptions": {
    "target": "es2022",
    "lib": ["es2022", "esnext.disposable", "dom"]
  }
}

#名前付きタプル要素と匿名タプル要素の混合

タプルに名前付き要素と匿名要素を混ぜることが出来るようになりました。

tsx
type Anonymous = [T, T];

// 名前付きタプル
type Named = [first: T, second: T];

// TS 5.2でサポートされた記述
type Merged = [...Anonymous, ...Named];

// TS 5.2でサポートされた記述
type TwoOrMore = [fiest: T, second: T, ...[]];

#配列のユニオン型に対するメソッドの改善

今まで filter や reduce、find などのメソッドを配列のユニオン型に対して呼ぶと、“配列の要素に互換性がないためメソッドを呼べない!“というエラーが吐かれていました。

tsx
const array: string[] | number[] = [];

array.filter((x) => !!x);

今後は、このようなケースでもユニオン型の要素を持つ配列にフォールバックされるためエラーが吐かれなくなります。しかしstring[] | number[](string | number)[] のように解釈されるようになる点には注意が必要です。

tsx
array.filter((x: string | number) => {
  return !!x;
});

#非破壊的な配列メソッドのサポート

ES2023 の新機能である Change Array by copy、非破壊的な配列操作を行えるメソッドのサポートがされました。

https://github.com/tc39/proposal-change-array-by-copy

tsx
// myArray.reverse()
myArray.toReversed()

// myArray.sort((a, b) => ...)
myArray.toSorted((a, b) => ...)

// myArray.splice(start, deleteCount, ...items)
myArray.toSpliced(start, deleteCount, ...items)

// myArray[index] = updatedValue
myArray.with(index, updatedValue)

#参考文献

編集