TypeScriptチームがTypeScript 3.6のリリースを発表した。厳格になったジェネレータ、Promiseに関する開発者エクスペリエンスの向上、配列スプレッドの精度改善、新しくなったTypeScript Playgroundが含まれている。
TypeScript 3.6より前は、値がyieldされたものか、ジェネレータから返されたものかを区別することはできなかった。また、yieldの型はanyであると想定されていた。
TypeScript 3.6リリースでは、yieldの型が厳密にチェックされるようになるとともに、新しい型であるGenerator
でジェネレータを表現するようになる。ジェネレータの型チェックの改善をサポートするため、Iterator
およびIteratorResult
の型宣言に、いくつかの型パラメータが新たに設けられる。さらに、新しいGenerator
型もIterator
で、 return
とthrow
の両メソッドが常に使用可能になる。
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氏が詳しく説明する。
createIncrementalProgram
とcreateIncrementalCompilerHost
という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
"として定義される GlobalFetch
がWindowOrWorkerGlobalScope
に置き換えられるNavigator
の非標準プロパティの一部が削除されるexperimental-webgl
コンテキストがwebgl
とwebgl2
に置き換えられる- JSDocコメントがマージされなくなる
- キーワードにエスケープシーケンスを含めることはできない
TypeScriptチームは現在、TypeScript 3.6で導入された機能を型定義の生成で活用するなど、TypeScript 3.7に向けた機能に既に取り組んでいる。
TypeScriptコミュニティはまた、10月11日に開催される題2回のTSConfイベントの準備中で、TypeScriptの創始者であるAnders Hejlsberg氏が基調講演を行う予定である。
TypeScriptは,Apache 2ライセンス下で利用可能なオープンソースソフトウェアである。コントリビューションやフィードバックはTypeScript GitHubプロジェクトを通じて募集されている。いずれもTypeScriptコントリビューションガイドラインおよびMicrosoftオープンソースコード規範に従うことが必要だ。