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 宣言に似ています。
const getResource = (label: string) => {
return {
[Symbol.dispose]: {
console.log(`Disposed ${label}!`)
}
}
}
{
using resource = getResource("fish")
} // Disposed fish!
using 宣言のクリーンアップはスタックのように振る舞います。
const race = () => {
using turtle = getResource("turtle");
using rabbit = getResource("rabbit");
};
race();
// Dispose rabbit!
// Dispose turtle!await using 宣言とSymbol.asyncDispose メソッド
クリーンアップ関数が非同期の場合は、Symbol.asyncDispose を利用します。
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 の場合と同様に振る舞います。
using cleanup = new DisposableStack();
cleanup.defer(() => {
console.log("Cleanup!");
});非同期なクリーンアップ関数を実行する場合は、DisposableStack の代わりに AsyncDisposableStack を利用します。
await using stack = new AsyncDisposableStack();
stack.defer(async () => {
await someAsyncCleanupOperaiton();
});Explicit Resource Management を利用する
利用したい場合は、"esnext.disposable"を lib に設定する必要があります。
{
"compilerOptions": {
"target": "es2022",
"lib": ["es2022", "esnext.disposable", "dom"]
}
}名前付きタプル要素と匿名タプル要素の混合
タプルに名前付き要素と匿名要素を混ぜることが出来るようになりました。
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 などのメソッドを配列のユニオン型に対して呼ぶと、“配列の要素に互換性がないためメソッドを呼べない!“というエラーが吐かれていました。
const array: string[] | number[] = [];
array.filter((x) => !!x);今後は、このようなケースでもユニオン型の要素を持つ配列にフォールバックされるためエラーが吐かれなくなります。しかしstring[] | number[] が(string | number)[] のように解釈されるようになる点には注意が必要です。
array.filter((x: string | number) => {
return !!x;
});非破壊的な配列メソッドのサポート
ES2023 の新機能である Change Array by copy、非破壊的な配列操作を行えるメソッドのサポートがされました。
https://github.com/tc39/proposal-change-array-by-copy
// 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)