BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース ジェネレータとPromise処理が改善されたTypeScript 3.6

ジェネレータとPromise処理が改善されたTypeScript 3.6

原文(投稿日:2019/09/04)へのリンク

TypeScriptチームがTypeScript 3.6のリリースを発表した。厳格になったジェネレータ、Promiseに関する開発者エクスペリエンスの向上、配列スプレッドの精度改善、新しくなったTypeScript Playgroundが含まれている。

TypeScript 3.6より前は、値がyieldされたものか、ジェネレータから返されたものかを区別することはできなかった。また、yieldの型はanyであると想定されていた。

TypeScript 3.6リリースでは、yieldの型が厳密にチェックされるようになるとともに、新しい型であるGeneratorでジェネレータを表現するようになる。ジェネレータの型チェックの改善をサポートするため、IteratorおよびIteratorResultの型宣言に、いくつかの型パラメータが新たに設けられる。さらに、新しいGenerator型もIteratorで、 returnthrowの両メソッドが常に使用可能になる。

interface Generator<T = unknown, TReturn = any, TNext = unknown>
        extends Iterator<T, TReturn, TNext> {
    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
    return(value: TReturn): IteratorResult<T, TReturn>;
    throw(e: any): IteratorResult<T, TReturn>;
    [Symbol.iterator](): Generator<T, TReturn, TNext>;
}

returnで返された値とyieldで返された値を区別するために、 IteratorResult型は判別共用体(discriminated union type)に変換される。

一連の変更による結果について、TypeScriptプログラムマネージャのDaniel Rosenwasser氏が次のように説明している。

TypeScript 3.6では、イテレータを直接扱う場合に、イテレータからの値を絞り込むことができるようになりました。next()呼び出しからジェネレータに渡すことができる型を正しく表すために、TypeScript 3.6では、ジェネレータ関数の本体内でのyieldの使用も適切に推測します。

TypeScript 3.6では、Promiseの誤用に関する開発者エクスペリエンスが改善されている。Promiseを扱う場合にありがちな間違いとして、結果を他の関数に渡す前に、.then()あるいは結果のawaitを忘れる、というものがあるが、エラーメッセージを改善することで、開発者により適切な情報が提供されるようになった。例えば,

// Argument of type 'Promise<User>' is not assignable to parameter of type 'User'.
//   ...
// Did you forget to use 'await'?

TypeScriptは、JavaScriptのさまざまなバージョンをターゲットとしてサポートしている。ES2015以前のコンパイルターゲットに対して、TypeScriptでは通常、for/ofループおよび配列スプレッドの構文を生成するが、古いバージョンのJavaScriptでは、これらはかなりヘビーウエイトな場合がある。TypeScript 3.6では、 "--downlevelIteration"フラグを使用した別タイプのイテレーションをサポートして、配列のみをサポートする、より単純なデフォルト出力が提供されるようになった。このコンパイルフラグを使用すると、トランスパイル(transpile)されたコードの精度が向上する反面、コードサイズはかなり大きくなる。

--downlevelIteration以外にもTypeScript 3.6では、slice()とビルトインの使用に代わるものとして、新たに__spreadArraysヘルパが設けられ、古いターゲットでECMAScript 2015を使用する場合にも、より正確な動作をサポートするようになった。__spreadArraysヘルパは、TypeScriptヘルパのランタイムライブラリであるtslibでも使用できる。

TypeScript 3.6より前は、アンビエントコンテキストのgetおよびsetアクセサは許可されず、プロパティと同じものとして扱われていた。ECMAScriptクラスフィールドの提案では、これとは異なる挙動が導入される可能性がある。この挙動をサポートし、サブクラスで適切なエラーを提供するために、アンビエントコンテキストにおけるゲッタとセッタが、TypeScript 3.6でサポートされるようになった。

declare class Foo {
    // Allowed in 3.6+.
    get x(): number;
    set x(val: number): void;
}

TypeScript 3.7はこの改善を活用して、生成された.d.tsファイルのget/setアクセサが生成されるようになる。

TypeScript 3.6より前のバージョンでは、クラスと関数のマージはどのような状況でもエラーになっていたが、TypeScript 3.6では、アンビエントクラスと関数をマージできるようになった。このマージの変更により、呼び出し可能なコンストラクタパターン(callable constructor pattern)を簡単に表現することが可能になり、名前空間とこれらの宣言をマージできるようになる。TypeScript 3.7では、.jsファイルから生成される.d.tsファイルで、クラスライクな関数の呼び出し可能性と構築可能性をキャプチャできるようになる。

TypeScript 3.0では、ビルド時に他のプロジェクトの参照をサポートする--buildフラグが追加された。またTypeScript 3.4では--incrementalフラグが導入されて、以前のコンパイルの情報を保持することにより、特定のファイルのみをリビルドできるようになった。これらのフラグは従来、Webpackなどサードパーティのビルドツールでは機能しなかったが、TypeScript 3.6では、プロジェクト参照とインクリメンタルプログラムビルドを操作するための2つのAPIセットが提供されている。Rosenwasser氏が詳しく説明する。

createIncrementalProgramcreateIncrementalCompilerHostという2つのAPIを使って、--incrementalビルドを生成できるようになりました。新たに公開されたreadBuilderProgram関数を使用すれば、このAPIによって生成された.tsbuildinfoファイルから古いプログラムインスタンスを再ハイドレート(re-hydrate)することも可能です。これは、新しいプログラムの生成にのみ使用可能である、という意味です(つまり、返されたインスタンスは変更できず、create*Program関数のoldProgramパラメータとしてのみ使用可能である、ということです)。プロジェクト参照を活用するために、createSolutionBuilder関数が新たに公開されました。この関数は、新しい型であるSolutionBuilderのインスタンスを返します。

TypeScript Playgroundが、Artem Tyurin氏の尽力で大幅に更新された。プレイグラウンドが大幅に改善されると同時に、TypeScriptによる実験も容易になった。

TypeScript 3.6の他の改善点は次のとおりだ。

  • ES2015以降のターゲットを出力する場合の、識別子としてUnicode文字をサポート
  • SystemJS内でのimport.metaのサポート
  • セミコロンを考慮したコード編集
  • よりスマートになった自動インポート

TypeScript 3.6では、潜在的に互換性のない変更が導されているが、これらはすべて、ECMAScript標準で新たに追加された機能または変更を使用した結果である。

  • "constructor"という名前のクラスメンバがコンストラクタになる
  • グローバル変数のwindowが"type Window"として定義されなくなり、今後は"type Window & typeof globalThis"として定義される
  • GlobalFetchWindowOrWorkerGlobalScopeに置き換えられる
  • Navigatorの非標準プロパティの一部が削除される
  • experimental-webglコンテキストがwebglwebgl2に置き換えられる
  • JSDocコメントがマージされなくなる
  • キーワードにエスケープシーケンスを含めることはできない

TypeScriptチームは現在、TypeScript 3.6で導入された機能を型定義の生成で活用するなど、TypeScript 3.7に向けた機能に既に取り組んでいる。

TypeScriptコミュニティはまた、10月11日に開催される題2回のTSConfイベントの準備中で、TypeScriptの創始者であるAnders Hejlsberg氏が基調講演を行う予定である。

TypeScriptは,Apache 2ライセンス下で利用可能なオープンソースソフトウェアである。コントリビューションやフィードバックはTypeScript GitHubプロジェクトを通じて募集されている。いずれもTypeScriptコントリビューションガイドラインおよびMicrosoftオープンソースコード規範に従うことが必要だ。

この記事に星をつける

おすすめ度
スタイル

BT