Microsoftは、オープンソースのプログラミング言語の最新版「TypeScript 3.7」のβ版を公開した。オプショナルチェイニングの実装が目玉だ。nullish coalescing演算子の導入の他、「--declaration」と「--allowJs」を組み合わせて使えるようになるなど、多数の新機能を提供する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
Microsoftは2019年10月1日(米国時間)、オープンソースのプログラミング言語の最新版「TypeScript 3.7」のβ版を公開した。β版は機能が完備しており、今後バグを修正し、パフォーマンスと安定性をさらに高めた上で、2019年11月に正式版をリリースする予定だ。
TypeScriptは、静的型付けができる言語で、JavaScriptのスーパーセット。ECMA規格に従った最新のJavaScriptの機能を、古いWebブラウザやランタイムが扱えるようにコンパイルすることもできる。
TypeScript 3.7のβ版は、NuGetを使うか、次のコマンドラインのように、npmを使ってインストールできる(β版であるため、「@beta」が必要)。
npm install typescript@beta
TypeScript 3.7は「Visual Studio 2019」「Visual Studio 2017」の他、「Visual Studio Code」と「Sublime Text」でも利用できる。TypeScript 3.7の主な特徴は次の通り。
TypeScript 3.7では、ECMAScriptで最も要望の高い機能の一つであるオプショナルチェイニングを実装した。
オプショナルチェイニングの基本的な働きは、nullやundefinedが発生した場合に、式の実行を直ちに停止できるコードの作成を可能にすることだ。このためにオプションプロパティアクセスのための新しい「?.」演算子を追加した。
let x = foo?.bar.baz();
例えば、上のコードスニペットは、次のように記述するのと同じことになる。
let x = (foo === null || foo === undefined) ? undefined : foo.bar.baz();
nullish coalescing演算子は、オプショナルチェイニングと密接に関係するECMAScript機能だ。演算子として「??」を用いる。
この機能は、nullやundefinedを処理する際に、デフォルト値に“フォールバックする”方法と考えることができる。
let x = foo ?? bar();
例えば、上のコードスニペットは、次のように記述するのと同じことになる。
let x = (foo !== null && foo !== undefined) ? foo : bar();
予期せぬ状態が発生すると、エラーをスロー(throw)する関数がある。こうした関数は“アサーション”関数と呼ばれる。
TypeScript 3.7では、アサーション関数をモデル化する“アサーションシグネチャ”という新しい考え方を導入した。
TypeScriptでは、「--declaration」フラグを使って、「.ts」や「.tsx」ファイルのようなソースTypeScriptファイルから、「.d.ts」ファイル(宣言ファイル)を生成できる。.d.tsファイルを使用すると、オリジナルのソースコードを再チェック、ビルドすることなく、他のプロジェクトに対して型チェックを行うことができる。
残念ながら、--declarationには、TypeScriptとJavaScriptの入力ファイルを混合できる「--allowJs」のような設定とともに使えないという制限があった。
TypeScript 3.7では、この2つの機能を組み合わせて利用できるようになる。allowJsを使う場合、TypeScriptはベストエフォートでJavaScriptソースコードを理解し、同等の表現で.d.tsファイルに保存する。例えば、次のようなコードを扱ったとしよう。
/** * @callback Job * @returns {void} */ /** Queues work */ export class Worker { constructor(maxDepth = 10) { this.started = false; this.depthLimit = maxDepth; /** * NOTE: queued jobs may add more items to queue * @type {Job[]} */ this.queue = []; } /** * Adds a work item to the queue * @param {Job} work */ push(work) { if (this.queue.length + 1 > this.depthLimit) throw new Error("Queue full!"); this.queue.push(work); } /** * Starts the queue if it has not yet started */ start() { if (this.started) return false; this.started = true; while (this.queue.length) { /** @type {Job} */(this.queue.shift())(); } return true; } }
上記のコードが次のような.d.tsファイルに変換される。
/** * @callback Job * @returns {void} */ /** Queues work */ export class Worker { constructor(maxDepth?: number); started: boolean; depthLimit: number; /** * NOTE: queued jobs may add more items to queue * @type {Job[]} */ queue: Job[]; /** * Adds a work item to the queue * @param {Job} work */ push(work: Job): void; /** * Starts the queue if it has not yet started */ start(): boolean; } export type Job = () => void;
TypeScriptのプロジェクト参照を使うと、コードベースを分割してコンパイルを簡単に高速化できる。ただし依存関係を設定していなかったり、コードが古かったりすると動作しない。
TypeScript 3.7では、依存関係のあるプロジェクトを開く場合、TypeScriptが自動的にソースの.ts/.tsxファイルを使用する。これにより、セマンティック操作が最新になっていて、きちんと機能していれば、プロジェクト参照を使用するプロジェクトであっても、編集エクスペリエンスが向上する。
このような挙動が必要ない場合は、コンパイラオプション「disableSourceOfProjectReferenceRedirect」で無効にできる。
関数の呼び出しを忘れるのは、珍しいことではないが、危険だ。関数に引数がなかったり、プロパティと思われるような名前が付いていたりする場合に忘れやすい。
例えば、次のコードは、「isAdministrator」を呼び出すのを忘れており、管理者以外のユーザーであっても構成を編集できてしまう。
interface User { isAdministrator(): boolean; notify(): void; doNotDisturb?(): boolean; } // later... // Broken code, do not use! function doAdminThing(user: User) { // oops! if (user.isAdministrator) { sudo(); editTheConfiguration(); } else { throw new AccessDeniedError("User is not an admin"); } }
TypeScript 3.7では、このような部分を特定して、次のように、問題のある箇所を伝える。
function doAdminThing(user: User) { if (user.isAdministrator) { // ~~~~~~~~~~~~~~~~~~~~ // error! This condition will always return true since the function is always defined. // Did you mean to call it instead?t
今回のチェック機能はこれまでのTypeScriptの挙動とかなり異なる。そのため、非常に「保守的」な動作をする。エラーだとされるのはif内だけだ。つまり、オプションプロパティやstrictNullChecksがオフの場合、後ほどifの本体内で関数が呼び出されている場合には、次の例のようにエラーにはならない。
interface User { isAdministrator(): boolean; notify(): void; doNotDisturb?(): boolean; } function issueNotification(user: User) { if (user.doNotDisturb) { // OK, property is optional } if (user.notify) { // OK, called the function user.notify(); } }
TypeScriptのビルトインフォーマッタにも改良を加えた。JavaScriptの自動セミコロン挿入(ASI)ルールによって行末のセミコロンがオプションとなっている場所で、セミコロンの挿入と削除を自動化できるようになった。
この設定は「Visual Studio Code Insider」で利用でき、「Visual Studio 16.4 Preview 2」でも、「ツールオプション」メニューで利用できる。
「insert」(挿入)または「remove」(削除)の値を選ぶと、TypeScriptサービスで提供される自動インポートや抽出した型、他の生成コードのフォーマットにも影響する。設定をデフォルト値「ignore」(無視)のままにすると、生成コードを、現在のファイルで検出されたセミコロンの傾向に合わせて整形する。
Copyright © ITmedia, Inc. All Rights Reserved.