Experts.jp日本に、もっとエキスパートを。3第一回は、「なぜTypeScriptか?」という話を書きました。前回はTypeScriptで開発する際の環境についてがテーマでした。2015において積極的に利用するべき構文を紹介していきます。TypeScriptの近況をお伝えしておきます。TypeScriptの現在のバージョンは1.7.5で、この後もまだまだアップデート予定は詰まっています。アップデートの予定はたくさんありますが、これは必ずしも機能が十分に揃っていないということを意味しません。2015のsuperset+型のための構文が導入された言語です。TypeScriptの今後のアップデートはTypeScript自体の使い勝手や、型の柔軟性を改善するためのものが大部分。2015の構文の追加はGeneratorsくらいのものです。2015による記述を行うためには十分成熟している、といえます。次に挙げる機能を使う場合、多くのブラウザで動作させるために何らかの後処理が必要になります。2015としてのmoduleの仕様は決まりましたが、ブラウザ上で動かせる状態にはありません。そのため、require.jsやbrowserify、SystemJSなどのツールが必要。Node.js上で動作させる場合はCommonJSスタイルのJavaScriptとして出力できるためTypeScriptコンパイラによる変換だけで利用可能。es6でのみ利用可である(es5で動く形式に変換できない)ため、利用したい場合はbabelによる変換が必要。仕組み上es5で動く形に変換ができない(つまり、全くの新機能である)ものもいくつかあります。ブラウザなどの進歩を待ちましょう。2015的に書くことにします。古くからのJavaScriptユーザとしては見慣れないかもしれない、そして別の言語に慣れている人には、比較的読みやすい記法でしょう。これから紹介するTypeScript独自の記法ではないものは正式にJavaScriptの仕様になったものであるため、今後数年以内に徐々にすべてのJavaScriptコードが本稿で紹介されるような記法へと移行されていく...といいなぁ。playgroundですぐに試せるリンクをなるべく添えています。Playground上で、変数名などにマウスカーソルをホバーさせるとどういう型として解釈されているか確認できるのでいろいろ試してみてください。Playgroundはmodule周りのサポートがすっぽり抜け落ちているので、その辺りは割愛しています。前回の記事を参考に、自分で環境を整え、試してみてください。TypeScript独自の構文まずは、TypeScript独自の構文について述べておきます。独自の構文といっても、型に関する部分についてなのでプログラムの動作には影響しません。プログラムの堅牢さ、分かりやすさ、保守しやすさによい影響があります。詳しく知りたい場合は、筆者の書いた別の解説やTypeScriptの更新差分解説を参照してください。型注釈の基本TypeScript最大の特徴として、型の存在とそれを利用した静的なチェックがあります。JavaScriptにももちろん型は存在しています。RegExpなどなど多岐に渡りますがJavaScriptでは変数と型を結びつけるということをしませんでした。TypeScriptでは変数に型を明示的に指定(注釈を与える)ことにより、静的なチェックやIDEによる支援を受けることができます。変数や引数について型の指定ができる箇所は多くありますが、基本的に次の箇所だけマークしておけば多くの局面に対応できます。型名という形式で記述します。anyなど、組み込みの型と、DateやRegExpなど、見知ったJavaScriptのオブジェクトも存在しています。boolean[];Playgroundで試す簡単ですね。型パラメータの考え方は、JavaやC#を知っている人であれば、馴染みのある記法でしょう。TypeScriptは配列だけは特別扱いをしており、Arrayなどの記法の他に、boolean[]という記法をも許しています。これも、JavaやC#を知る人であれば、見たことがある記法かもしれません。TypeScriptでは、配列についてはboolean[]の記法を使うほうが一般的です。Interfacesインタフェースは、あるオブジェクトについての性質を記述し、それに名前をつけることができます。JavaやC#ではあるクラスに特定の実装を強制するものとして使いますが、TypeScriptではその範囲にとどまりません。クラス化するほどでもない、サーバから受け取るデータについて名前をちょいちょいと与える場合などに使われる場合が多いです。2015の構文の説明に入っていきます。筆者が育てている4つの個人リポジトリのソースコードを見て、実際に使っているもののみを抜粋してきました。2015以前よりも改善されている構文である!といえます。ついて紹介しておきます。5のときからあるディレクティブです。"setterは存在していない";Playgroundで試す多くの効能があるため、ここでは詳細には解説しません。modeになるためです。modeではなくなってしまいます。strict";を書いておき、挙動を揃えておきます。これはトイレに行った後に手を洗うというレベルのエチケットなので、tslintなどを活用して忘れないように気をつけましょう。constを紹介します。JavaScriptではvarというキーワードを使って変数定義をしていました。constではvarに対して次の違いがあります。ブロックスコープである同じ変数名を複数回定義しようとするとエラーになる変数の巻き上げは行われるが宣言前にアクセスするとエラーになるconstの場合、さらに追加があります。varの不思議な挙動について理解しておかねばならない時代も過去のものとなりそうです。多くの場合で単純にvarをletに置き換えできるし、そうしたほうがよいでしょう。varをletに置き換えて動かなくなるようなコードは、JavaScriptの不快な仕様を利用した悪いコードだと考え、リファクタリングするべきです。es5などでコンパイルした時はletがvarに変換されるため、実行時エラーは発生しなくなってしまいます。実用上はコンパイル時にそれと分かればとりあえずは問題ないでしょう。Classesオブジェクト指向な言語であればだいたい存在するクラスです。2015から導入されました。5までは、prototypeという仕組みを使ってオブジェクト指向なコードを書いていました。prototypeにも良いところがあり、悪いモノでもないのですが、広く知られているという分かりやすさ、関連する記述がひとところにまとまっているという利点を考えると、やはりclassが使えるというのはありがたいものです。今後、prototypeの出番は大きく減るでしょう。いえ、classの裏側はprototypeであるため、今まで使えたハックも利用可能ではあります。表示されるconsole.log(obj.hi());Playgroundで試すJavaやC#を見慣れているユーザであれば、大変親しみやすいコードになったと思います。PlaygroundでどういうES5なコードに変換されるかを確認してみてください。これを手書きで書くのは、チーム内の人数が多くなれば多くなるほど辛く感じるでしょう。クラスが使えるようになりましたが、だからといってなんでもかんでもクラスにしなければならないわけではありません。今までどおり、関数や普通のオブジェクトを使うのが適していると思った場合はどんどん使って構いません。無理にクラスを使おうとするほうが、意図のわかりづらい、よくないコードになってしまうでしょう。"!"のように、アクセス修飾子付きで仮引数を宣言すると、自動的に自分のプロパティとしてセットされます。name;のように自分で代入しましょう。2015コードが生成されるかをチェックしてみるとよいでしょう。Modulesモジュールです。2015では、ついにモジュールという概念が、JavaScriptの仕様として盛り込まれました。今までのJavaScriptにはモジュールの仕様が正式にはなく、AMDやCommonJSなど、それを埋めるための(ECMAScriptではない)仕様が複数考えだされ、実装されてきました。Node.jsではCommonJSのモジュールに仕様に近いものが採用されています。1ファイル毎に名前空間が分割されていて、どの識別子を外部に公開するかを選択していきます。モジュールの仕様は、静的に(つまり実行することなく)ソースコード間の依存関係が解決できるようになっています。そのため、今までのJavaScriptのコードとはかけ離れた、全く新しい構文をもっています。コード例を見ていきましょう。いう3つのコードを利用します。3ファイルあるので、モジュールが3つあることになります。TypeScriptでコンパイルするとそうではなくなってしまうので明示的に指定しておく。TypeScriptでコンパイルするとそうではなくなってしまうので明示的に指定しておく。表示されるconsole.log(utilB.hi());残念ながら、Playgroundで試すことができないので、お手元に環境を作って試してみてください。exportして、importするだけの仕様ではありますが、慣れるまでは正しい記法がわかりづらく戸惑いを覚えるでしょう。TypeScriptの利点として、動作しない書き方をした場合きっちりコンパイルエラーにしてくれるので試行錯誤する手間が省けます。functions(アロー関数)です。5までのJavaScriptの関数は、thisの値が他言語ユーザの期待とだいぶかけ離れた動作をしていて辛かったです。アロー関数では期待する挙動と実際の挙動の齟齬がだいぶ軽減されています。5の関数と大差ありませんね。タイプする文字数が減って嬉しいですが、まあ、その程度です。名前付きアロー関数は作ることができませんので、素直に変数に代入しましょう。次の例を見てみましょう。Sample("TypeScript");obj.method();Playgroundで試すアロー関数の特徴が顕著に出ていますね。理由が明確に説明できない限り、今後はfunctionと記述する関数ではなく、アロー関数を使うべきでしょう。具体的に、今までのfunctionを使うのは名前付き関数を作りたい場合や、thisの値を変更するタイプのAPIをもつライブラリを使う場合などです。operators(展開演算子)について取り上げます。2015からの導入になりますが、特にお世話になるのはデフォルト値付き引数でしょう。"TypeScript";のような、JavaScriptユーザ以外にはわかりにくいイディオムを取る必要がありましたがだいぶわかりやすくなりましたね。stringは文字列の生成が今までより簡単にできるようになりました。これにより、文字列を結合してメッセージなどを生成するのが格段に読みやすくなります。Gruntfile.jsやgulpfile.jsでできると、設定ファイルも大変見やすく保守も簡単になります。name);Playgroundで試すまさにテンプレートですね。stringという機能もあるのですが、あまり有効な使いみちがないのと、活用した有名なライブラリなども登場してきていないので入門レベルでは気にする必要はないでしょう。2015から、非同期処理における標準のAPIが定義されました。それがPromiseです。Promiseは「約束する」の名の示すとおり、将来的に処理結果を返すことを約束し、その予約表を先に払い出すイメージです。Promiseの結果は成功か失敗の2状態で表されます。es5で動作しているため、Promiseの型定義が存在していません。コンパイルエラーが出ていてもRunすることはできますが、できれば手元で試してみるのがよいでしょう。Promiseは今後さまざまな標準APIの一部として使われることになります。APIなどを使うようになると、まず間違いなく触らなければいけなくなるため、今のうちに確実にマスターしておくことをお勧めします。azuさんのPromise本が大変わかりやすいので熟読すると得るものが大きいと思います。まとめいかがでしょうか。わかりやすく使いやすい変更が多いので、今すぐにでも使い始められると思います。TypeScriptなコードから書き始め、徐々に適用範囲を広げていってみてください。