HTML5Experts.jp

TypeScriptを使ってECMAScript 2015時代のJavaScriptを先取りしよう!

わかめです。これから、TypeScriptを使ってECMAScript 2015スタイルのコードを書く方法を紹介します。連載の初回となる本稿では、ECMAScript 2015やTypeScriptの魅力について、TypeScript用エディタの案内をしていきます。

TypeScriptとは?

TypeScriptはMicrosoft社が開発しているAltJSの1つです。AltJSとは、ある言語Xから、JavaScriptへと変換(トランスパイル)して使う言語の総称です。Typeという名の通り、JavaScriptの世界に静的な型付けを持込み、JavaやC#のようにコンパイル時に整合性のチェックを行うことができるようにしたものです。

見事チェックにパスしたら、TypeScriptからJavaScriptへと変換され、JavaScriptとして実行できる、という按配です。

TypeScriptは全くの新言語、というわけではありません。ECMAScript 5のsupersetとして設計されているため、皆さんが慣れ親しんだJavaScriptの構文に少しの+αを加えた言語がTypeScriptです。ECMAScript 5のsupersetなのですが、設計当初よりクラスなどのECMAScript 2015の要素も含んでいました。ゆくゆくはECMAScript 2015のsupersetにもなっていくことでしょう。

また、多くのECMAScript 2015用の構文をECMAScript 5の構文に変換して出力することができるため、現在のECMAScript 5をサポートしている(つまりほとんどの)ブラウザで動作させることが可能です。ECMAScript 5を改良すべく生まれたECMAScript 2015の仕様を先取りし、既存のブラウザ上で使いはじめることができる環境として、TypeScriptは魅力的でしょう。

TypeScriptのECMAScript 5の範囲での説明は、型の国のTypeScriptなどを参照してください。

TypeScriptとECMAScript 2015

ECMAScriptというのは、JavaScriptの仕様の元になる仕様です。現在、多くのブラウザではECMAScript 5の仕様にもとづき実装が行われています。2015/06/18にECMAScript 6th editionとして、ECMAScript 2015が策定されました。ECMAScript 2015という名前よりも、ECMAScript 6や、もっと縮めてES6という名前のほうが目にする機会が多いかもしれません。

これにより、今後ブラウザでのECMAScript 2015のサポートの進みが早くなっていくものと考えられます。現在の各ブラウザでのES6の機能の実装状況はes6 compat tableで確認するのが便利でしょう。

ECMAScript 2015には、言語仕様に素敵な要素が多く追加されています。いくつかを確認していきましょう。コード例を見て、「え、これ今までできなかったの?」と思ってしまうかもしれません。TypeScriptなら、今使えます。

let str = "外側の変数";
console.log(str); // 外側の変数 と表示される
{
  let str = "内側の変数"; // このブロックでだけ有効
  console.log(str); // 内側の変数 と表示される
}
console.log(str); // 外側の変数 と表示される!戻ってる!

const str = "test";
str = "re-assignment"; // 仕様上SyntaxErrorになる。ブラウザによっては未実装で単に無視される。

class SampleA {
  constructor() {
    this.name = "vvakame";
  }

hi() { console.log("Hi! " + this.name); } }

// 上記と等価なECMAScript 5なコード function SampleB() { this.name = "vvakame"; } Object.defineProperty(SampleB.prototype, "hi", { enumerable: false, configurable: true, writable: true, value: function () { console.log("Hi! " + this.name); } });

// 実行結果は同じ new SampleA().hi(); new SampleB().hi();

"use strict";

function Sample() { // this.name を設定する this.name = "vvakame";

// 普通の関数とアロー関数で this の値を比べてみよう! var func1 = function() { console.log("func1: " + JSON.stringify(this)); }; var func2 = () => { console.log("func2: " + JSON.stringify(this)); };

// func1: undefined と表示される // 非直感的。いやわかるでしょ?という人はJavaScript慣れしています! func1();

// func2: {"name":"vvakame"} と表示される // 直感的! func2(); }

new Sample();

function hello(word = "ECMAScript 2015") {
  // word が指定されなかった場合のデフォルト値を指定できる
  console.log("Hello, " + word + "!");
}
hello("JavaScript"); // Hello, JavaScript! と表示される
hello();             // Hello, ECMAScript 2015! と表示される

let name = "vvakame";
let like = "cat";

console.log(${name} ♥ ${like}); // vvakame ♥ cat と表示される

なぜTypeScriptか?

さて、本記事ではタイトルの通り、TypeScriptを推していくわけですが、他の選択肢についても言及していきます。読者自身が何をほしいか、どうやって自由自在にコードを書きたいか、作りたいものがどれくらいの規模なのか、それぞれをよく考えて適切な選択をしていただけるといいなと考えています。もちろん、おすすめはTypeScriptですが、読者層別におすすめのツールを取り上げていきます。

Babel

Babelは旧名が6to5と呼ばれていたツールで、sebmck氏によって開発されています。Babelはソースコードのコンパイルが必要なツールで、通常foo.es6というファイルをfoo.jsに変換します。

現在ECMAScript 2015や、さらに次のECMAScript 7でコードを書くには一番進んでいて、将来のブラウザでもそのまま動く可能性が高いと言えます。現在のJavaScript(ECMAScript 5)に言語としての不満がない人や、Ruby on Railsなどの動的型付けの言語+フレームワークで十分に開発できている人に向いているでしょう。

Playgroundも用意されているため、まずはブラウザ上で試してみるとよいでしょう。

Flow

FlowはFacebookが開発しているツールで、JavaScriptに対して静的な型チェックを提供します。Flow自体の開発言語はOCamlです。Flowの型チェックは、型推論や段階的な型付けを前面に押し出しているようです。JavaScriptのコード自体、関数や変数のユースケースから型を推論させることや、TypeScriptと同様に手で型の指定を記述することもできます。制作元が同じだけあって、FacebookのReactと組み合わせて利用することも考慮されているようです。

もし、Reactを使うようであれば、利用を検討してみてもいいかもしれません。

TypeScript

さて、最後に我らがTypeScriptです。TypeScriptは、Microsoftが3年近く前から開発し続けているツールです。TypeScriptはソースコードのコンパイルが必要なツールで、通常foo.tsというファイルをfoo.jsに変換します。

TypeScriptは静的型付けの言語で、コンパイル時に多くの整合性のチェックを行うことができます。例えば「Personクラスには必ずnameプロパティがある」とか「mapメソッドは第一引数に関数を取る」などがソースコードの字面上から解析できれば、それに違反している(つまりは間違った)コードを実行するよりも前の段階で検出することができます。これは、JavaやC#といった言語と同じ性質であると言えます。

反対に、静的型付けではない、動的型付けである言語はJavaScriptやRubyなどです。これらの言語は実行時に必要なプロパティやメソッドなどが存在していればよい、という態度です。静的・動的な型付けのどちらが優れているということはありませんが、その言語を使う個人や組織毎に得手・不得手があるでしょう。

別な切り口として、IDEやエディタをどの程度使っているかも検討材料になります。静的型付けの言語では実行せずともどういうプロパティやメソッドがあるかがわかります。そのため、IDEによる強力な支援が得られやすいのです。

例えば、str.と打った時に利用可能なメソッドの一覧が提示されたり、変数やメソッドのリネームが一発でできたり、関数の参照元を全てリストアップするなどの作業を行うことができます。

反対に、動的にメソッドが増えたりする言語では正確なサジェストを行うのが大変難しいです。例えば、RubyのActiveRecord(ORマッパライブラリ)では、DBのテーブルのカラムに合わせて利用可能なメソッドが増えたりします。便利といえば便利ですが、IDEがライブラリのすること全てを把握してプログラムとして実行することなく呼び出し可能なメソッドの一覧を正しく提示することは現実としては不可能でしょう。

静的型付けな言語ではコンパイル時に検査されるおかげで、リファクタリングも抜け漏れなくできているという勇気が持てます。JavaScriptを書いている時に「テストを書き足りていないのではないか」「実行時にundefinedなプロパティを触ってしまいエラーになるのではないか」という恐怖を感じたことはありませんか?TypeScriptではこの恐怖をかなり減じ、勇気あるリファクタリングを行うことができます。常にきれいなコードを保つ足がかりをTypeScriptは提供してくれるのです。

Playgroundも用意されているため、まずはブラウザ上で試してみると良いでしょう。

なお、WebComponentsが流行ったほうが、Reactが主流の未来より僕は楽だよ派の筆者としては遺憾なのですが、TypeScript 1.6でJSXサポートが入る予定です。

エディタの紹介

TypeScriptはコンパイラ自身にLanguage Serviceという、まさにエディタのためのような機能が組み込まれています。TypeScriptを開発するための総本山(なにせMicrosoft製ですからね)であるVisual StudioでもこのLanguage Serviceから得た情報を元に処理しています。つまり、TypeScriptでは数多くのエディタでVisual Studio相当の入力補完や、フォーマットなどが得られるようになっているのです。

いくつか、箇条書きで紹介していきます。

まとめ

TypeScriptの環境を作り、しばらくコードを書いてみて、あまりに窮屈すぎる!エディタの恩恵を感じない!と思ったらbabelを使ってみるとよいでしょう。

次回は開発環境の構築と、TypeScriptを取り巻く周辺ツールについて解説します。