<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>わかめまさひろ &#8211; HTML5Experts.jp</title>
	<atom:link href="/vvakame/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>TypeScriptで今すぐ使える実践的『ECMAScript 2015』</title>
		<link>/vvakame/18057/</link>
		<pubDate>Fri, 15 Jan 2016 00:00:34 +0000</pubDate>
		<dc:creator><![CDATA[わかめまさひろ]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=18057</guid>
		<description><![CDATA[連載： TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！ (3)TypeScriptを使ってECMAScript 2015時代のコードを書く 3 第一回は、「なぜTypeSc...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/ts-es2015/" class="series-312" title="TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！" data-wpel-link="internal">TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！</a> (3)</div><h1>TypeScriptを使ってECMAScript 2015時代のコードを書く 3</h1>

<p><a href="https://html5experts.jp/vvakame/16241/" data-wpel-link="internal">第一回</a>は、「なぜTypeScriptか？」という話を書きました。<a href="https://html5experts.jp/vvakame/17004/" data-wpel-link="internal">前回</a>はTypeScriptで開発する際の環境についてがテーマでした。今回は、最後の締めくくりとしてECMAScript 2015において積極的に利用するべき構文を紹介していきます。</p>

<p>まず、TypeScriptの近況をお伝えしておきます。TypeScriptの現在のバージョンは1.7.5で、この後もまだまだ<a href="https://github.com/Microsoft/TypeScript/wiki/Roadmap" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アップデート予定</a>は詰まっています。アップデートの予定はたくさんありますが、これは必ずしも機能が十分に揃っていないということを意味しません。</p>

<p>第一回で触れたとおり、TypeScriptはECMAScript 2015のsuperset+型のための構文が導入された言語です。TypeScriptの今後のアップデートはTypeScript自体の使い勝手や、型の柔軟性を改善するためのものが大部分。その証左として、1.5.3より後の1.6.2、1.7.5のアップデートではECMAScript 2015の構文の追加はGeneratorsくらいのものです。つまり、TypeScriptはすでにECMAScript 2015による記述を行うためには十分成熟している、といえます。</p>

<p>次に挙げる機能を使う場合、多くのブラウザで動作させるために何らかの後処理が必要になります。</p>

<ul>
<li>Modules

<ul>
<li>ECMAScript 2015としてのmoduleの仕様は決まりましたが、ブラウザ上で動かせる状態にはありません。そのため、<a href="http://requirejs.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">require.js</a>や<a href="http://browserify.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">browserify</a>、<a href="https://github.com/systemjs/systemjs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SystemJS</a>などのツールが必要。</li>
<li>なお、Node.js上で動作させる場合はCommonJSスタイルのJavaScriptとして出力できるためTypeScriptコンパイラによる変換だけで利用可能。</li>
</ul></li>
<li>Generators

<ul>
<li><code>--target es6</code>でのみ利用可である（es5で動く形式に変換できない）ため、利用したい場合は<a href="https://babeljs.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">babel</a>による変換が必要。</li>
</ul></li>
</ul>

<p>また、仕組み上es5で動く形に変換ができない（つまり、全くの新機能である）ものもいくつかあります。ブラウザなどの進歩を待ちましょう。</p>

<p>本稿では、すべてのサンプルコードは現代的に、つまりECMAScript 2015的に書くことにします。古くからのJavaScriptユーザとしては見慣れないかもしれない、そして別の言語に慣れている人には、比較的読みやすい記法でしょう。</p>

<p>これから紹介するTypeScript独自の記法ではないものは正式にJavaScriptの仕様になったものであるため、今後数年以内に徐々にすべてのJavaScriptコードが本稿で紹介されるような記法へと移行されていく…といいなぁ。</p>

<p>また、本稿に出てくるサンプルコードは<a href="http://www.typescriptlang.org/Playground" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TypeScript playground</a>ですぐに試せるリンクをなるべく添えています。Playground上で、変数名などにマウスカーソルをホバーさせるとどういう型として解釈されているか確認できるのでいろいろ試してみてください。Playgroundはmodule周りのサポートがすっぽり抜け落ちているので、その辺りは割愛しています。<a href="https://html5experts.jp/vvakame/17004/" data-wpel-link="internal">前回</a>の記事を参考に、自分で環境を整え、試してみてください。</p>

<h2>TypeScript独自の構文</h2>

<p>まずは、TypeScript独自の構文について述べておきます。独自の構文といっても、型に関する部分についてなのでプログラムの動作には影響しません。プログラムの堅牢さ、分かりやすさ、保守しやすさによい影響があります。</p>

<p>詳しく知りたい場合は、<a href="http://typescript.ninja/typescript-in-definitelyland/types-basic.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">筆者の書いた別の解説</a>や<a href="http://qiita.com/vvakame/items" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TypeScriptの更新差分解説</a>を参照してください。</p>

<h3>型注釈の基本</h3>

<p>TypeScript最大の特徴として、型の存在とそれを利用した静的なチェックがあります。</p>

<p>JavaScriptにももちろん型は存在しています。string, number, Date, RegExpなどなど多岐に渡りますがJavaScriptでは変数と型を結びつけるということをしませんでした。</p>

<p>TypeScriptでは変数に型を明示的に指定（注釈を与える）ことにより、静的なチェックやIDEによる支援を受けることができます。</p>

<p>変数や引数について型の指定ができる箇所は多くありますが、基本的に次の箇所だけマークしておけば多くの局面に対応できます。</p>

<ul>
<li>初期化なしの変数宣言</li>
<li>関数の仮引数</li>
<li>関数の戻り値の型</li>
<li>型パラメータ</li>
</ul>

<p>TypeScriptでは、変数や仮引数などの後に<code>: 型名</code>という形式で記述します。number, boolean, string, void, anyなど、組み込みの型と、DateやRegExpなど、見知ったJavaScriptのオブジェクトも存在しています。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

// 関数の仮引数と戻り値の型
function concat(a: string, b: string): string {
    return a + b;
}

// 変数の型
let obj1: RegExp;
// 初期化子がある場合、わざわざ型注釈を明記しなくとも自動的に推論される
let obj2 = /^Hi!$/;

let array1: Array;
// array1 と全く同じ意味合い
let array2: boolean[];</pre><p></p>

<p><a href="http://goo.gl/TJ3p76" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>簡単ですね。型パラメータの考え方は、JavaやC#を知っている人であれば、馴染みのある記法でしょう。TypeScriptは配列だけは特別扱いをしており、<code>Array</code>などの記法の他に、<code>boolean[]</code>という記法をも許しています。これも、JavaやC#を知る人であれば、見たことがある記法かもしれません。TypeScriptでは、配列については<code>boolean[]</code>の記法を使うほうが一般的です。</p>

<h3>Interfaces</h3>

<p>インタフェースは、あるオブジェクトについての性質を記述し、それに名前をつけることができます。JavaやC#ではあるクラスに特定の実装を強制するものとして使いますが、TypeScriptではその範囲にとどまりません。</p>

<p>クラス化するほどでもない、サーバから受け取るデータについて名前をちょいちょいと与える場合などに使われる場合が多いです。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

interface Sample {
    str: string;
    func: (n: string) =&gt; number;
    methodA(): void;
}

let obj: Sample;
obj.str;
obj.func("test");
obj.methodA();</pre><p></p>

<p><a href="http://goo.gl/HH4hLd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<h2>ECMAScript 2015</h2>

<p>さて、それではECMAScript 2015の構文の説明に入っていきます。筆者が育てている4つの個人リポジトリのソースコードを見て、実際に使っているもののみを抜粋してきました。</p>

<p>つまり、ここで紹介している構文は使い勝手がよく、ECMAScript 2015以前よりも改善されている構文である！といえます。</p>

<h3>use strict</h3>

<p>まずは、 &#8220;use strict&#8221;; について紹介しておきます。これはECMAScript 5のときからあるディレクティブです。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

// getterのみあり setterなし
let obj = {
    get str() {
        return "Hi!";
    }
};

// エラーにしてくれる！
// Uncaught TypeError: Cannot set property str of # which has only a getter
// "use strict"; がないと、単に無視されるので値がセットされない謎のバグになり苦しみのたうつ
obj.str = "setterは存在していない";</pre><p></p>

<p><a href="http://goo.gl/BDx6bd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>多くの効能があるため、ここでは詳細には解説しません。ここで解説した理由は、<a href="http://www.ecma-international.org/ecma-262/6.0/#sec-strict-mode-code" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ECMAScript 2015の仕様</a>上、後述のクラスやモジュールの内部は暗黙的にstrict modeになるためです。TypeScriptで書いたコードをコンパイルするとクラスやモジュールの構文も変換されてしまい、暗黙的にstrict modeではなくなってしまいます。</p>

<p>そのため、後々ECMAScript 2015が無変換で動く時代になった時に困らぬよう、今のうちからすべてのファイルの先頭に<code>"use strict";</code>を書いておき、挙動を揃えておきます。これはトイレに行った後に手を洗うというレベルのエチケットなので、<a href="https://github.com/palantir/tslint" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">tslint</a>などを活用して忘れないように気をつけましょう。</p>

<h3>let, const</h3>

<p>let, constを紹介します。JavaScriptでは<code>var</code>というキーワードを使って変数定義をしていました。let, constではvarに対して次の違いがあります。</p>

<ul>
<li>ブロックスコープである</li>
<li>同じ変数名を複数回定義しようとするとエラーになる</li>
<li>変数の巻き上げは行われるが宣言前にアクセスするとエラーになる</li>
</ul>

<p>constの場合、さらに追加があります。</p>

<ul>
<li>宣言時に初期化必須</li>
<li>値の置き換え不可</li>
</ul>

<p>便利ですね。varの不思議な挙動について理解しておかねばならない時代も過去のものとなりそうです。多くの場合で単純にvarをletに置き換えできるし、そうしたほうがよいでしょう。varをletに置き換えて動かなくなるようなコードは、JavaScriptの不快な仕様を利用した悪いコードだと考え、リファクタリングするべきです。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

let objA = "Aだよ！";
// ブロックスコープだ！ varはブロックスコープではない
{
    let objA = "Aだけど2番目だよ！";
    // Aだけど2番目だよ！ と表示される
    console.log(objA);
}
// Aだよ！ と表示される
console.log(objA);

// 2重に宣言してもエラーにならない
var objB: any;
var objB: any;

// 2重に宣言するとちゃんとエラーになる（TypeScript上でもプログラム実行時でも）
let objC: any;
let objC: any;

// 定数として宣言すると値の書き換えはエラーになる（TypeScript上でもプログラム実行時でも）
const objD = "Hi!";
objD = "Bye!";

// ちなみに値のさらに中身を書き換えるのは問題ない
const objE = {
    str: "Hi!"
};
objE.str = "Bye!";
// 対策（実行時エラーになる）
const objF = Object.freeze({
    str: "Hi!"
});
objF.str = "Bye!";</pre><p></p>

<p><a href="http://goo.gl/wG8Aqq" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>なお、TypeScriptで<code>--target es5</code>などでコンパイルした時はletがvarに変換されるため、実行時エラーは発生しなくなってしまいます。実用上はコンパイル時にそれと分かればとりあえずは問題ないでしょう。</p>

<h3>Classes</h3>

<p>オブジェクト指向な言語であればだいたい存在するクラスです。JavaScriptではECMAScript 2015から導入されました。ECMAScript 5までは、prototypeという仕組みを使ってオブジェクト指向なコードを書いていました。</p>

<p>prototypeにも良いところがあり、悪いモノでもないのですが、広く知られているという分かりやすさ、関連する記述がひとところにまとまっているという利点を考えると、やはりclassが使えるというのはありがたいものです。</p>

<p>今後、prototypeの出番は大きく減るでしょう。とはいえ、classの裏側はprototypeであるため、今まで使えたハックも利用可能ではあります。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

class Sample {
    name: string;

    constructor(name: string, public extention = "!") {
        this.name = name;
    }

    hi(): string {
        return `Hi, ${this.name}${this.extention}`;
    }
}

let obj = new Sample("TypeScript");
// Hi, TypeScript! と表示される
console.log(obj.hi());</pre><p></p>

<p><a href="http://goo.gl/xC81cv" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>JavaやC#を見慣れているユーザであれば、大変親しみやすいコードになったと思います。ぜひ、PlaygroundでどういうES5なコードに変換されるかを確認してみてください。これを手書きで書くのは、チーム内の人数が多くなれば多くなるほど辛く感じるでしょう。</p>

<p>また、クラスが使えるようになりましたが、だからといってなんでもかんでもクラスにしなければならないわけではありません。今までどおり、関数や普通のオブジェクトを使うのが適していると思った場合はどんどん使って構いません。無理にクラスを使おうとするほうが、意図のわかりづらい、よくないコードになってしまうでしょう。</p>

<p>TypeScriptのみの独自仕様として、constructorで<code>public extention = "!"</code>のように、アクセス修飾子付きで仮引数を宣言すると、自動的に自分のプロパティとしてセットされます。ECMAScript 2015の仕様に準拠したコードを書きたい場合は、<code>name</code>プロパティのように、フィールドの宣言をしてから<code>this.name = name;</code>のように自分で代入しましょう。</p>

<p>気になる場合は、tscでのコンパイル時に<code>--target es6</code>を指定してコンパイルし、どのようなpure ECMAScript 2015コードが生成されるかをチェックしてみるとよいでしょう。</p>

<h3>Modules</h3>

<p>モジュールです。ECMAScript 2015では、ついにモジュールという概念が、JavaScriptの仕様として盛り込まれました。今までのJavaScriptにはモジュールの仕様が正式にはなく、AMDやCommonJSなど、それを埋めるための（ECMAScriptではない）仕様が複数考えだされ、実装されてきました。Node.jsではCommonJSのモジュールに仕様に近いものが採用されています。</p>

<p>ECMAScript 2015でのモジュールの仕様は、ざっくりいうと 1ファイル=1モジュール という仕様です。1ファイル毎に名前空間が分割されていて、どの識別子を外部に公開するかを選択していきます。</p>

<p>モジュールの仕様は、静的に（つまり実行することなく）ソースコード間の依存関係が解決できるようになっています。そのため、今までのJavaScriptのコードとはかけ離れた、全く新しい構文をもっています。</p>

<p>コード例を見ていきましょう。utilA.ts, utilB.ts, main.ts という3つのコードを利用します。3ファイルあるので、モジュールが3つあることになります。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

export default function() {
    return "Hi! from utilA";
}</pre><p></p>

<p></p><pre class="crayon-plain-tag">"use strict";

export function hi() {
    return "Hi! from utilB";
}</pre><p></p>

<p></p><pre class="crayon-plain-tag">"use strict";
// es6 moduleを使うと自動的に use strict した事になる。
// しかし、TypeScriptでコンパイルするとそうではなくなってしまうので明示的に指定しておく。

import utilA from "./utilA";
import {hi} from "./utilB";
import * as utilB from "./utilB";

// Hi! from utilA と表示される
console.log(utilA());
// Hi! from utilB と表示される
console.log(hi());
// Hi! from utilB と表示される
console.log(utilB.hi());</pre><p></p>

<p>残念ながら、Playgroundで試すことができないので、お手元に環境を作って試してみてください。</p>

<p>exportして、importするだけの仕様ではありますが、慣れるまでは正しい記法がわかりづらく戸惑いを覚えるでしょう。TypeScriptの利点として、動作しない書き方をした場合きっちりコンパイルエラーにしてくれるので試行錯誤する手間が省けます。</p>

<h3>Arrow functions</h3>

<p>Arrow functions（アロー関数）です。ECMAScript 5までのJavaScriptの関数は、thisの値が他言語ユーザの期待とだいぶかけ離れた動作をしていて辛かったです。アロー関数では期待する挙動と実際の挙動の齟齬がだいぶ軽減されています。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

// 引数なしの場合 括弧は必要
let funcA = () =&gt; {
    console.log("Hi!");
};
// Hi! と表示される
funcA();

// 引数1個の場合、括弧をつけることもできる
let funcB = (name: string) =&gt; {
    console.log(`Hi! ${name}`);
};
// Hi! TypeScript と表示される
funcB("TypeScript");

// 引数が1個の場合、括弧を省略して仮引数名のみを書くことができる
// ただし、括弧を省略する場合仮引数の型を指定することはできない
// このため、ここではfuncC変数に型を指定している
let funcC: (name: string) =&gt; void = name =&gt; {
    console.log(`Hi! ${name}`);
};
// Hi! TypeScript と表示される
funcC("TypeScript");
// 既に型がついている場合そのまま省略できる
funcC = name =&gt; {
    console.log(`Hi! ${name}`);
};
// Hi! TypeScript と表示される
funcC("TypeScript");

let funcD = (name: string, ...rest: string[]) =&gt; {
    console.log(`Hi! ${name} and ${rest.join(", ")}`);
};
// Hi! TypeScript and ECMAScript 2015, ECMAScript 2016 と表示される
funcD("TypeScript", "ECMAScript 2015", "ECMAScript 2016");</pre><p></p>

<p><a href="http://goo.gl/9UY2O3" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>この使い方では、EMCAScript 5の関数と大差ありませんね。タイプする文字数が減って嬉しいですが、まあ、その程度です。名前付きアロー関数は作ることができませんので、素直に変数に代入しましょう。</p>

<p>次の例を見てみましょう。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

class Sample {
    constructor(public name: string) {
    }

    toString(): string {
        return `${this.name}!`;
    }

    method() {
        // ここはmethodのトップレベルです

        let funcA = () =&gt; {
            // arguments にアクセスできない
            // thisの値はmethodのトップレベルと変わらない
            console.log(`Hi, ${this}`);
        };
        let funcB = function() {
            // arguments にアクセスできる
            // thisの値は undefined
            console.log(`Hi, ${this}`);
        };

        // Hi, TypeScript! と表示される
        funcA();
        // Hi, undefined と表示される
        funcB();
    }
}

let obj = new Sample("TypeScript");
obj.method();</pre><p></p>

<p><a href="http://goo.gl/dOSfsx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>アロー関数の特徴が顕著に出ていますね。</p>

<p>理由が明確に説明できない限り、今後はfunctionと記述する関数ではなく、アロー関数を使うべきでしょう。具体的に、今までのfunctionを使うのは名前付き関数を作りたい場合や、thisの値を変更するタイプのAPIをもつライブラリを使う場合などです。</p>

<h3>Default parameters, Rest parameters, Spread operators</h3>

<p>Default parameters（デフォルト値付き引数）、rest parameters（可変長引数）、Spread operators（展開演算子）について取り上げます。これらもECMAScript 2015からの導入になりますが、特にお世話になるのはデフォルト値付き引数でしょう。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

// デフォルト値付き引数
// 当てはまる引数が渡されない場合、指定された値がデフォルト値として利用される
function hi(name = "TypeScript") {
    return `Hi! ${name}`;
}
// Hi! TypeScript と表示される
console.log(hi());
// Hi! ECMAScript 2015 と表示される
console.log(hi("ECMAScript 2015"));

// 可変長引数
function bye(...names: string[]) {
    if (names.length === 0) {
        return `Bye, JavaScript`;
    }
    return `Bye, ${names.join(", ")}`;
}
// Bye, JavaScript と表示される
console.log(bye());
// Bye, JavaScript, ECMAScript 3 と表示される
console.log(bye("JavaScript", "ECMAScript 3"));

function goodOldDays() {
    return ["JavaScript", "ECMAScript 3", "ECMAScript 5"];
}

let array = goodOldDays();
// spread（展開）される
// Bye, JavaScript, ECMAScript 3, ECMAScript 5 と表示される
console.log(bye(...array));
// 同上
console.log(bye(array[0], array[1], array[2]));</pre><p></p>

<p><a href="http://goo.gl/8mjHsl" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>ECMAScript 5までは、<code>p = p || "TypeScript";</code>のような、JavaScriptユーザ以外にはわかりにくいイディオムを取る必要がありましたがだいぶわかりやすくなりましたね。</p>

<h3>Template string</h3>

<p>Template stringは文字列の生成が今までより簡単にできるようになりました。これにより、文字列を結合してメッセージなどを生成するのが格段に読みやすくなります。Gruntfile.jsやgulpfile.jsでできると、設定ファイルも大変見やすく保守も簡単になります。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

let name = "TypeScript";
// Hi! TypeScript と表示される
console.log(`Hi! ${name}`);

name = "ECMAScript 2015"
// Hi! ECMAScript 2015 と表示される
console.log(`Hi! ${name}`);

// Hi! ECMAScript 2015 と表示される
console.log("Hi! " + name);</pre><p></p>

<p><a href="http://goo.gl/tFF05r" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>まさにテンプレートですね。</p>

<p>Tagged template stringという機能もあるのですが、あまり有効な使いみちがないのと、活用した有名なライブラリなども登場してきていないので入門レベルでは気にする必要はないでしょう。</p>

<h3>Promises</h3>

<p>ECMAScript 2015から、非同期処理における標準のAPIが定義されました。それがPromiseです。Promiseは「約束する」の名の示すとおり、将来的に処理結果を返すことを約束し、その予約表を先に払い出すイメージです。Promiseの結果は成功か失敗の2状態で表されます。</p>

<p></p><pre class="crayon-plain-tag">"use strict";

let p1 = Promise.resolve(true);
p1.then(value =&gt; {
    // true と表示される
    console.log(value);
});

let p2 = Promise.reject("何かのエラー！");
p2.then(value =&gt; {
    // rejectの場合はここに到達しない
    console.log(value);
}, err =&gt; {
    // 何かのエラー！ と表示される
    console.log(err);
});

let p3 = Promise.reject("何かのエラー！");
p3.catch(err =&gt; {
    // 何かのエラー！ と表示される
    console.log(err);
});

let p4 = new Promise((resolve, reject) =&gt; {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                resolve(xhr.responseText);
            } else {
                reject(xhr);
            }
        }
    }
    xhr.open("GET", "http://www.typescriptlang.org/");
    xhr.send();
});
p4
    .then(text =&gt; {
        // 通信が成功していたらHTMLがどばー！と表示される
        console.log(text);
    })
    .catch((xhr: XMLHttpRequest) =&gt; {
        // 通信に失敗していたらステータスコードが表示される
        console.log(xhr.status);
    });</pre><p></p>

<p><a href="http://goo.gl/l5KCJN" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playgroundで試す</a></p>

<p>Playgroundは<code>--target es5</code>で動作しているため、Promiseの型定義が存在していません。コンパイルエラーが出ていてもRunすることはできますが、できれば手元で試してみるのがよいでしょう。</p>

<p>Promiseは今後さまざまな標準APIの一部として使われることになります。ブラウザ上で動くコードを書いている場合でも、ServiceWorkerやfetch APIなどを使うようになると、まず間違いなく触らなければいけなくなるため、今のうちに確実にマスターしておくことをお勧めします。azuさんの<a href="http://azu.github.io/promises-book/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Promise本</a>が大変わかりやすいので熟読すると得るものが大きいと思います。</p>

<h2>まとめ</h2>

<p>いかがでしょうか。わかりやすく使いやすい変更が多いので、今すぐにでも使い始められると思います。まずは、既存コードなしの100% TypeScriptなコードから書き始め、徐々に適用範囲を広げていってみてください。</p>

<p>CoffeeScriptやECMAScript 5なコードからは遅かれ早かれ移行しなければならないと思いますので、本記事を参考に徐々に実践を始めてみてください！それでは良いTypeScript &amp; ECMAScript 2015ライフを！</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！]]></series:name>
	</item>
		<item>
		<title>TypeScript の開発環境構築と周辺ツールの紹介</title>
		<link>/vvakame/17004/</link>
		<pubDate>Thu, 15 Oct 2015 01:00:10 +0000</pubDate>
		<dc:creator><![CDATA[わかめまさひろ]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=17004</guid>
		<description><![CDATA[連載： TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！ (2)前回はなぜTypeScriptか？という話を書きました。今回はTypeScriptを使うとして、どういう環境を...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/ts-es2015/" class="series-312" title="TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！" data-wpel-link="internal">TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！</a> (2)</div><p><a href="https://html5experts.jp/vvakame/16241/" data-wpel-link="internal">前回</a>はなぜTypeScriptか？という話を書きました。今回はTypeScriptを使うとして、どういう環境を作れば気持ちよく開発できるかについて解説します。</p>

<p>本稿に出てくるサンプルをまとめた<a href="https://github.com/vvakame/typescript-project-sample" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">リポジトリ</a>を随時メンテしております。時期によっては、本記事の内容に沿わない（より磨かれた）状態になっているかもしれません。</p>

<p>TypeScriptの開発環境が指すものは2つあります。IDEやエディタといった、本当に開発を行うための環境と、初期設定を行ったりリリースビルドを作ったりするためのタスクランナーの二種類です。</p>

<p>本記事ではお勧めの構成として、Visual Studio Code+grunt+dtsmを用いていきます。別構成として、Atomとgulp、tsdについても言及します。いずれの構成でも、Mac OS X、Windows、Linuxといった主要なプラットフォームで同じように動かすことができます。</p>

<h2>TypeScriptのインストール</h2>

<p>Node.js+npmはすでに導入してある前提で進めます。<code>$ npm install -g typescript</code>か、それで失敗する環境の場合は<code>$ sudo npm install -g typescript</code>を行ってください。現時点（2015年10月9日）では、TypeScript 1.6.2がインストールされます。TypeScriptコンパイラ（tscコマンド）のバージョンを確認するには、<code>$ tsc -v</code>を実行します。</p>

<h2>tsconfig.json</h2>

<p>tsconfig.jsonはTypeScript 1.5.3から登場した要素です。TypeScriptコードをコンパイルする際に、コンパイルオプションとコンパイル対象のtsコードの指定をひとまとめにした設定ファイルです。</p>

<p>今までTypeScriptのコードをJavaScriptにコンパイルするには、tscコマンドにコンパイルオプションや.tsファイルのパスを与えてコンパイルしていました。この方法の問題点は、どういうオプションを渡せばプロジェクトを正しくコンパイルすることができるかわからないということです。また、ファイル同士の依存関係の記述方法も問題でした。reference commentと呼ばれる、TypeScriptコード同士の依存関係をコード中に書く方式が一番最初にありました。これだと依存関係をいちいち記述するのが大変面倒くさく、コンパイル時のエントリーポイントとなるコードを間違えると生成されるコードが変わり、その影響で依存順次第で実行時エラーになる…というパターンもありました。</p>

<p>後述するgruntやgulpなどのタスクランナーを使えば、プロジェクトメンバーやコントリビュータとの手法の共有はできるようになります。依存関係についても毎回同じ方法でコンパイルするようになるため、コンパイル開始のエントリポイントとなる1つのファイルからtree状に依存関係を記述していく方法で楽をすることができるようになりました。しかし、IDEやエディタからはGruntfile.jsやgulpfile.jsの設定値は活用することができないため、入力補完やエラー報告の正確さに不満がありました。</p>

<p>これら、コンパイル方法の指定・TypeScriptコード同士の依存関係を解決できるのが、ここで紹介するtsconfig.jsonです。tsconfig.jsonはTypeScriptコンパイラ、人間、エディタの3者が理解することができる、便利なコンパイル方法の記述手段なのです。</p>

<p>Microsoft先生は最近OSSに対する貢献をどんどん強化してきていますが、まだNode.js+npmやエディタ周りの文化に対する理解が薄いです。そのためtsconfig.jsonについて、めちゃめちゃ使いにくい仕様が生まれています。たとえば、TypeScript 1.5.3ではfilesプロパティにコンパイル対象とするファイルの一覧を1つ1つ書かねばならず、大変面倒くさいです。TypeScript 1.6.0-betaではexcludeプロパティに除外するファイルやフォルダを指定できますが、filesプロパティとの併用はできませんし一部除外解除の設定もできません。basarat氏がatom-typescriptで実装している、filesGlobsプロパティのように、ワイルドカードや除外ルールの組み合わせで順番や対象をコントロールできる方式のほうが優れていると思うのですけどね。</p>

<p>とはいえ、tsconfig.jsonを使いこなすと便利です。今後はtsconfig.jsonがあるとTypeScriptでコードを書くにあたりいろいろな恩恵が得られると思いますので、本連載ではtsconfig.jsonを中心とした環境づくりを紹介していきます。</p>

<p>では、実際にtsconfig.jsonを使ってみましょう。tsconfig.jsonは特別な理由がない限り、プロジェクトルートに1つ置いて使います。TypeScript 1.6.0-beta以降では、<code>--init</code>オプションが使えるため、<code>tsc --init</code>を実行するとリスト1が得られます。</p>

<p></p><pre class="crayon-plain-tag">{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es3",
        "noImplicitAny": false,
        "outDir": "built",
        "rootDir": ".",
        "sourceMap": false
    },
    "exclude": [
        "node_modules"
    ]
}</pre><p></p>

<p>特にこだわりがなければ、このまま使いはじめてもよいでしょう。しかし、excludeプロパティだけでの運用は細やかなコントロールができないため難しいでしょう。</p>

<p>本連載では、リスト2の構成を使います。filesGlobプロパティはtscコマンドやVSCがサポートしているプロパティではありません。atom-typescriptやgrunt-tsconfig-update、gulp-tsconfig-updateによるfilesプロパティへの展開などのフローを組み合わせていくことでフォローしていきます。リスト2の設定であれば、libディレクトリ配下に置いたコード、testディレクトリ配下に置いたコード、typings配下に置いた型定義ファイルがコンパイル時に自動的に処理されるようになるでしょう。</p>

<p></p><pre class="crayon-plain-tag">{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": true,
        "experimentalDecorators": false,
        "sourceMap": true,
        "declaration": false,
        "noEmitOnError": true
    },
    "filesGlob": [
        "./lib/**/*.ts",
        "./lib/**/*.tsx",
        "!./lib/**/*.d.ts",
        "./test/**/*.ts",
        "./test/**/*.tsx",
        "!./test/**/*.d.ts",
        "./typings/**/*.ts",
        "./node_modules/typescript/lib/lib.es6.d.ts"
    ],
    "files": [
    ]
}</pre><p></p>

<p>tsconfig.jsonを用意したら、後は<code>$ tsc --project ./</code>または<code>$ tsc -p ./</code>とすることでコンパイルを行うことができます。直接tsconfig.jsonを指定するのではなく、tsconfig.jsonがあるディレクトリを指定するのがポイントです。</p>

<p>設定可能な項目については公式wikiの<a href="https://github.com/Microsoft/TypeScript/wiki/tsconfig.json" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">tsconfig.json</a>と<a href="https://github.com/Microsoft/TypeScript/wiki/Compiler-Options" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">コンパイラオプション</a>の項目を参照してください。</p>

<h2>型定義ファイルマネージャ</h2>

<p>TypeScriptでコードを書くにあたり、もっともつらく、面倒なことを示しておきます。</p>

<p>TypeScriptはJavaScriptのsupersetであるので、既存のjQueryやAngularJSなどのJavaScript製ライブラリも利用することができます。しかしながら、JavaScriptで書かれているということは、ソースコードの字面上からなんというプロパティがあって、なんという関数があって、変数の型が何か、なんて全然わからないわけです。そのため、既存ライブラリをTypeScriptで使おうと思ったら、人間が型の情報を手書きしてライブラリの全体像をTypeScriptコンパイラに教えてやらねばならないのです。</p>

<p>型情報を記述したファイルを型定義ファイルと呼んでいます。有名どころのライブラリであれば、<a href="https://github.com/borisyankov/DefinitelyTyped" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DefinitelyTyped</a>というリポジトリで型定義ファイルを見つけることができます。たとえば、<a href="https://github.com/borisyankov/DefinitelyTyped/blob/master/jquery/jquery.d.ts" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">jQuery</a>や<a href="https://github.com/borisyankov/DefinitelyTyped/blob/master/angularjs/angular.d.ts" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">AngularJS</a>、<a href="https://github.com/borisyankov/DefinitelyTyped/blob/master/node/node.d.ts" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Node.js</a>の型定義ファイルなどはすでに成熟したものが存在しています。これら有名どころのライブラリはただ単にダウンロードしてきて使えばよいですが、マイナーなライブラリや非公開の社内ライブラリの場合は、自分で型定義ファイルを書き起こさなければなりません。</p>

<p>とはいえ、たとえばjQueryであれば最低限<code>declare var $: any;</code>という型定義を書いておけば、コンパイルを通すことはできます。充実した型定義は開発を加速しますが、最初のうちはざっくりした定義を与えておき、後から必要に応じて徐々に拡充していけば十分です。その過程でバグもより多く見つかるようになっていくことでしょう。</p>

<p>これら、型定義ファイルを上手に管理するためのツールも記事内で紹介します。</p>

<h3>dtsm</h3>

<p>手前味噌ですが、筆者（わかめ）が製作している型定義ファイルマネージャです。詳しい紹介は（ちょっと古いですが）<a href="http://qiita.com/vvakame/items/38b953ab0f4de63cce8b" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Qiitaの記事</a>を参照していただければと思います。</p>

<p>TypeScript界でデファクトのtsdに対する優位点として、型定義ファイルを集めたリポジトリをまるごとcloneしてくるため、一度cloneした後は高速に動作し、オフラインでの検索やインストールが可能です。また、npmやbowerといった広く使われているパッケージマネージャと使い方をなるべく似せてあるため、学習コストが低くすみます。</p>

<p><code>npm install -g dtsm</code>でインストールできます。</p>

<p>一番シンプルな使い方は、<code>dtsm search ui-router</code>などで検索し、<code>dtsm install angular-ui-router/angular-ui-router.d.ts</code>や<code>dtsm install angular-ui-router</code>で型定義ファイルを取得します。取得した型定義ファイルはtypingsディレクトリに格納されます。</p>

<p>型定義ファイルの更新などに簡単に対応できるようにするには、<code>dtsm init</code>でdtsm.jsonを作成し、<code>dtsm install --save angular-ui-router</code>でdtsm.jsonに設定を書き込みます。更新は<code>dtsm update --save</code>で行うことができます。</p>

<p>企業内に閉じたgitリポジトリ上で管理されている型定義ファイルなども参照させることができます。</p>

<h3>tsd</h3>

<p>TypeScript界でデファクトで使われている型定義ファイルマネージャです。GitHubのAPIを叩いて型定義ファイルを取得するため、たまに動作が遅い時があったり、企業などで同一IPアドレスからの利用が多くなるとRate Limitがかかってしまい、Tokenの取得や設定が必要になったりする場合があります。</p>

<p><code>npm install -g tsd</code>でインストールできます。</p>

<p>一番シンプルな使い方は、<code>tsd query "*ui-router"</code>などで検索し、<code>tsd install angular-ui-router</code>で型定義ファイルを取得します。取得した型定義ファイルはtypingsディレクトリに格納されます。</p>

<p>型定義ファイルの更新などに簡単に対応できるようにするには、<code>tsd init</code>でtsd.jsonを作成し、<code>tsd install angular-ui-router --save</code>でtsd.jsonに設定を書き込みます。更新は<code>tsd reinstall --overwrite --save</code>で行うことができます。</p>

<h2>ビルドタスクとタスクランナー</h2>

<p>TypeScriptプロジェクトを運用するために必要なタスクの紹介と、<a href="http://gruntjs.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt</a>と<a href="http://gulpjs.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp</a>の2つのタスクランナーについて取り上げていきます。筆者は普段gruntを使っているため、gulp周りについて改善できそうな箇所があったら<a href="https://github.com/vvakame/typescript-project-sample" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">サンプルリポジトリ</a>に対してpull requestなどいただけたらと思います。</p>

<p>最低限必要なタスクはたった2つだけです。</p>

<p>1つ目は、tsconfig.jsonのfilesプロパティを更新するための<a href="https://www.npmjs.com/package/grunt-tsconfig-update" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-tsconfig-update</a>と<a href="https://www.npmjs.com/package/gulp-tsconfig-update" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp-tsconfig-update</a>です。grunt版は僕が、gulp版は<a href="http://qiita.com/laco0416/items/a51b7534ddc4aec63875" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">lacoくんが作って</a>くれました。</p>

<p>2つ目は、<code>tsc -p ./</code>相当の操作をしてくれる<a href="https://www.npmjs.com/package/grunt-ts" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-ts</a>（5.0.0-beta.4以上）か、<a href="https://www.npmjs.com/package/gulp-shell" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp-shell</a>です。tscコンパイラに指定する内容自体がtsconfig.jsonによって大幅に簡略化されたため、grunt-tsも<a href="https://www.npmjs.com/package/grunt-shell" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-shell</a>に置き換えてしまってよいかもしれません。</p>

<p>これに、いくつかのタスクをオプションで追加してもよいでしょう。候補を挙げておきます。</p>

<p>よくないスタイルのTypeScriptコードを検出し教えてくれる<a href="https://www.npmjs.com/package/tslint" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">tslint</a>と、それを各タスクランナー用に切り出した<a href="https://www.npmjs.com/package/grunt-tslint" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-tslint</a>と<a href="https://www.npmjs.com/package/gulp-tslint" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp-tslint</a>。</p>

<p>TypeScriptコードにフォーマッタを適用しきれいにしてくれる<a href="https://www.npmjs.com/package/typescript-formatter" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">typescript-formatter</a>と、それを各タスクランナー用に切り出した<a href="https://www.npmjs.com/package/grunt-typescript-formatter" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-typescript-formatter</a>と<a href="https://www.npmjs.com/package/gulp-tsfmt" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp-tsfmt</a>。</p>

<p>TypeScriptコードからドキュメントを生成してくれる<a href="https://www.npmjs.com/package/typedoc" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">typedoc</a>と、それを各タスクランナー用に切り出した<a href="https://www.npmjs.com/package/grunt-typedoc" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-typedoc</a>と<a href="https://www.npmjs.com/package/gulp-typedoc" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp-typedoc</a>。</p>

<p><a href="https://www.npmjs.com/package/dtsm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">dtsm</a>, <a href="https://www.npmjs.com/package/tsd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">tsd</a>と<a href="https://www.npmjs.com/package/grunt-dtsm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-dtsm</a>、<a href="https://www.npmjs.com/package/grunt-tsd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">grunt-tsd</a>、<a href="https://www.npmjs.com/package/gulp-tsd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">gulp-tsd</a>。</p>

<p>大部分がgrunt-shellやgulp-shellからの呼び出しでもよいような気がしますね…。</p>

<h2>エディタ</h2>

<p>最後にエディタです。記事で紹介するVisual Studio Code、Atom以外にも多様な選択肢があるため、自分が馴染んでいるエディタやIDEにもTypeScript用プラグインが存在しないか試してみるとよいでしょう。</p>

<p>多様な選択肢がある理由ですが、TypeScriptは単なるコンパイラ以外のさまざまな機能を持っています。たとえば、ソースコードをフォーマットする機能だとか、入力補完候補を生成する機能です。これら、エディタの機能実装をサポートする強力で便利な要素があるため、本家Visual Studioと比べ、遜色ない強力な補完機能を備えたエディタが多く存在しているわけです。</p>

<p>とはいえ、エディタやプラグイン毎にTypeScript本体への追従度や完成度に差があるため、「イマイチ使いにくいな…」と思ったら別のエディタを試してみるのがよいでしょう。</p>

<p>本記事では、筆者がメインで使っているVisual Studio CodeとAtomについて解説します。</p>

<h3>Visual Studio Code</h3>

<p><a href="https://code.visualstudio.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">VSC</a>はMicrosoftが作ってはいますが、<a href="http://electron.atom.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Electron</a>上に構築されたマルチプラットフォームのエディタです。本家Visual Studioと違い、プラットフォームの縛りはありませんし、無料です。オープンソースではないため、自力で機能追加やバグ修正ができないのは難点ではあります。</p>

<p>grunt-tsconfig-updateかgulp-tsconfig-updateとの併用が前提になりますが、正しいtsconfig.jsonさえ作ってしまえばさすが本家Microsoft製だけあって、期待どおりに正しく入力補完やエラーの報告を行ってくれるようになります。特に強い要望がなく、gruntまたはgulpの利用に抵抗がないのであればVSCを最初に試してみるのがよいでしょう。</p>

<h3>Atom + atom-typescript</h3>

<p><a href="https://atom.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Atom</a>はGitHubが作っているエディタです。<a href="https://atom.io/packages/atom-typescript" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">atom-typescript</a>プラグインを併用することで大変便利なTypeScript開発環境として利用することができます。</p>

<h2>まとめ（開発環境編）</h2>

<p>タスクランナーの設定とエディタの設定が終わり、JavaScriptとは比較にならぬリッチな開発環境を手に入れられたことでしょう。何か疑問や要望がある場合、<a href="https://github.com/vvakame/typescript-project-sample" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">サンプルリポジトリ</a>のIssueまでお寄せいただければ、筆者の人生がつらくなっていなくてTypeScriptに飽きていない限り、対応できると思います。今のところTypeScriptは3年近く飽きていないので、もうしばらくは飽きないと思うんですよね。</p>

<p>次回は、いよいよECMAScript 2015なコードをTypeScriptで書き始めていきます。</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！]]></series:name>
	</item>
		<item>
		<title>TypeScriptを使ってECMAScript 2015時代のJavaScriptを先取りしよう！</title>
		<link>/vvakame/16241/</link>
		<pubDate>Wed, 29 Jul 2015 03:00:19 +0000</pubDate>
		<dc:creator><![CDATA[わかめまさひろ]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[ECMAScript]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[TypeScript]]></category>

		<guid isPermaLink="false">/?p=16241</guid>
		<description><![CDATA[連載： TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！ (1)わかめです。これから、TypeScriptを使ってECMAScript 2015スタイルのコードを書く方法を紹...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/ts-es2015/" class="series-312" title="TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！" data-wpel-link="internal">TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！</a> (1)</div><p>わかめです。これから、TypeScriptを使ってECMAScript 2015スタイルのコードを書く方法を紹介します。連載の初回となる本稿では、ECMAScript 2015やTypeScriptの魅力について、TypeScript用エディタの案内をしていきます。</p>

<h2>TypeScriptとは？</h2>

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

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

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

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

<p>TypeScriptのECMAScript 5の範囲での説明は、<a href="http://typescript.ninja/typescript-in-definitelyland/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">型の国のTypeScript</a>などを参照してください。</p>

<h2>TypeScriptとECMAScript 2015</h2>

<p>ECMAScriptというのは、JavaScriptの仕様の元になる仕様です。現在、多くのブラウザではECMAScript 5の仕様にもとづき実装が行われています。2015/06/18にECMAScript 6th editionとして、<a href="http://www.ecma-international.org/ecma-262/6.0/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ECMAScript 2015が策定</a>されました。ECMAScript 2015という名前よりも、ECMAScript 6や、もっと縮めてES6という名前のほうが目にする機会が多いかもしれません。</p>

<p>これにより、今後ブラウザでのECMAScript 2015のサポートの進みが早くなっていくものと考えられます。現在の各ブラウザでのES6の機能の実装状況は<a href="https://kangax.github.io/compat-table/es6/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">es6 compat table</a>で確認するのが便利でしょう。</p>

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

<ul>
<li>letでブロックスコープ</li>
</ul>

<p></p><pre class="crayon-plain-tag">let str = "外側の変数";
console.log(str); // 外側の変数 と表示される
{
  let str = "内側の変数"; // このブロックでだけ有効
  console.log(str); // 内側の変数 と表示される
}
console.log(str); // 外側の変数 と表示される！戻ってる！</pre><p></p>

<ul>
<li>constも使える</li>
</ul>

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

<ul>
<li>prototypeの代わりにclass構文！</li>
</ul>

<p></p><pre class="crayon-plain-tag">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();</pre><p></p>

<ul>
<li>アロー関数でわかりやすいthisの振る舞い</li>
</ul>

<p></p><pre class="crayon-plain-tag">"use strict";

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

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

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

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

new Sample();</pre><p></p>

<ul>
<li>デフォルトパラメータ、便利です</li>
</ul>

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

<ul>
<li>文字列連結もお手軽に！</li>
</ul>

<p></p><pre class="crayon-plain-tag">let name = "vvakame";
let like = "cat";

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

<h2>なぜTypeScriptか？</h2>

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

<h3>Babel</h3>

<p><a href="https://babeljs.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Babel</a>は旧名が6to5と呼ばれていたツールで、<a href="https://github.com/sebmck" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">sebmck</a>氏によって開発されています。Babelはソースコードのコンパイルが必要なツールで、通常foo.es6というファイルをfoo.jsに変換します。</p>

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

<p><a href="http://goo.gl/7pWFB9" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playground</a>も用意されているため、まずはブラウザ上で試してみるとよいでしょう。</p>

<h3>Flow</h3>

<p><a href="http://flowtype.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Flow</a>はFacebookが開発しているツールで、JavaScriptに対して静的な型チェックを提供します。Flow自体の開発言語はOCamlです。Flowの型チェックは、型推論や段階的な型付けを前面に押し出しているようです。JavaScriptのコード自体、関数や変数のユースケースから型を推論させることや、TypeScriptと同様に手で型の指定を記述することもできます。制作元が同じだけあって、FacebookのReactと組み合わせて利用することも考慮されているようです。</p>

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

<h3>TypeScript</h3>

<p>さて、最後に我らがTypeScriptです。<a href="http://www.typescriptlang.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TypeScript</a>は、Microsoftが3年近く前から開発し続けているツールです。TypeScriptはソースコードのコンパイルが必要なツールで、通常foo.tsというファイルをfoo.jsに変換します。</p>

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

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

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

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

<p><a href="https://html5experts.jp/wp-content/uploads/2015/07/vsc11.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2015/07/vsc11.gif" alt="VisualStudioCodeによるコード補完の様子" width="600" height="450" class="alignnone size-medium wp-image-16341" /></a></p>

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

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

<p><a href="http://goo.gl/cC60Pk" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Playground</a>も用意されているため、まずはブラウザ上で試してみると良いでしょう。</p>

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

<h2>エディタの紹介</h2>

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

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

<ul>
<li><a href="https://www.microsoft.com/ja-jp/dev/default.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Visual Studio</a><br>MicrosoftのIDEの最有力候補。NuGetなど独自の生態系があるが最近だいぶOSS側に歩み寄ってきた。残念ながらWindowsでしか動かない。<br><br></li>
<li><a href="https://www.visualstudio.com/ja-jp/products/code-vs.aspx" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Visual Studio Code</a> <br>最近新登場したIDE。Windows, Mac, Linuxで動作する。Previewなだけあってまだまだ機能が足りないが十分動く。Macユーザである筆者のメイン環境その1。余談だが、内部的にGitHub社製Atomが使っているElectronというフレームワークを使っていて、IDE全体がHTML+JavaScriptで作られている。<br><br></li>
<li><a href="https://atom.io/packages/atom-typescript" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">atom-typescript</a> <br>GitHub社製の<a href="http://blog.atom.io/2015/06/25/atom-1-0.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Atom</a>エディタ用のプラグイン。筆者のメイン環境その2。<br><br></li>
<li><a href="https://github.com/palantir/eclipse-typescript" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">eclipse-typescript</a> <br>Eclipse用プラグイン。かなり長期間開発が継続されている。Eclipseユーザなら検討の価値があるかも。<br><br></li>
<li><a href="http://typecsdev.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">TypEcs</a><br>Eclipse用プラグイン。同上。<br><br></li>
<li><a href="https://github.com/clausreinke/typescript-tools" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">typescript-tools</a> <br>エディタそのものではないが、TypeScriptのLanguage Serviceをツール化したもの。vimやemacs、Sublime Text 3用のプラグインから利用されている。<br><br></li>
<li><a href="https://www.jetbrains.com/webstorm/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">WebStorm</a> <br>JetBrains社製のIDE。IntelliJ IDEAやPyCharm, PhpStormの仲間。ここに書いたが、WebStorm 10の時点ではLanguage Serviceを使っておらず、独自に解析しているためTypeScript用という観点で見た時は一歩劣る。筆者の旧メイン環境。</li>
</ul>

<h2>まとめ</h2>

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

<p>次回は開発環境の構築と、TypeScriptを取り巻く周辺ツールについて解説します。</p>
]]></content:encoded>
		
		<series:name><![CDATA[TypeScriptでECMAScript 2015時代のJavaScriptを先取りしよう！]]></series:name>
	</item>
	</channel>
</rss>
