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;
Copyright © ITmedia, Inc. All Rights Reserved.