update.AngularJSのようなクライアントMVCフレームワークを採用すると、クライアントサイドの規模が大きくなってくるので、できればJavaScriptじゃなくて型のあるプログラミング言語で開発したいですよね。AngularJSは独自のクラスシステムを持っていないし、モデルやコントローラを実装するためにベースクラスを継承したりする必要もないので、altJSとの相性がよくて組み合わせやすいです。altJSと言ってもたくさん種類がありますが、今回はTypeScriptを使ってAngularJSアプリを書くときのTipsやコツなどを紹介したいと思います。ベースとなるプロジェクトを作るAngularJSのコードを書くとき、JavaScriptであればおもむろに書き始めることも可能ですが、altJSを使う場合はコンパイルなどの手順が必要になるので、Gruntを使ったプロジェクトを作る必要があります。Gruntfileを1から書いてファイルの配置などを考えるのはちょっと面倒なので、yeomanを使うか、どこかからひな形を持ってくるのが楽です。yeomanを使うyeomanを使うならangular-generator-typescriptというのがあります。Typescript用のyeomanのgeneratorでもこれ9ヶ月間もメンテされてないので、TypeScriptのコンパイル通らないし、fork元で新しく追加されたテンプレートに追随できていないんですよね。requestがありました。generator-angular開発者が忙しくて放置されていたようですが、近いうちに取り込まれそうな雰囲気なので待つのがよさそう。ひな形を使うひな形を持ってくるならこちらがおすすめ。参考にさせてもらいました。https://github.com/vvakame/angularjs-typescriptこの記事の内容をまとめたプロジェクトも用意しました。テストの設定がなかったりしてちょっと物足りないかもしれませんが、よければ参考にしてください。IDEA/WebStormなどのIDEの利用は必須と言ってもいいでしょう。Project...]を開き、プロジェクトのタイプにWebを選んで、前述したプロジェクトの含まれるディレクトリを指定するだけです。これだけで、AngularJSのAPIもこんなふうに補完されます。IDEAには、AngularJS用のプラグインも用意されていて(WebStormには標準搭載)、HTMLの編集中にdirectiveの補完が効くので便利です。13の利用をおすすめします。Gruntfileをカスタマイズするyeomanで生成したりひな形に含まれているGruntfileはそのまま使ってもいいんですが、カスタマイズすることでさらに便利になります。型定義ファイルTypeScriptでは、既存のJavaScriptライブラリを利用するために型定義ファイル(拡張子が.d.tsのファイル)を用意する必要があります。型定義ファイルを扱うリポジトリはDefinitelyTypedがメジャーです。AngularJSの型定義ファイルももちろん用意されています。https://github.com/borisyankov/DefinitelyTypedangular-generatorで生成したプロジェクトではDefinitelyTypedを丸ごと落としてきているのですが、これはちょっとおおげさな気がします。そこで、型定義ファイルを取得するためのツールとしてtsdを使います。requestして取れるようにしてもらいました。)TypeScriptの型定義ファイル管理ツールtsdを使ってみたGruntからtsdを呼び出すには、将来的にはgrunt-tsdってのが提供されるようですが、現状ではgrunt-execを使います。grunt-execをインストールします。--save-devあとは、Gruntfileでこんなタスクを用意するだけです。ファイルの置き場所はtsd-config.jsonで制御します。}}TypeScriptコンパイルGruntでTypeScriptのコンパイルをするにはgrunt-typescriptを使い、Gruntfileに次のようなタスクを用意します。}}ここで、srcとdestの指定方法に少しコツがあります。srcを指定するには次のような2つの方法があります。配列で全ファイルを列挙する、またはワイルドカードで全ファイルを指定する。これはどちらでも好みで選んでいいと思います。destの指定方法も2種類あります。ディレクトリを指定すると、TypeScriptのソースと同じツリー構造でJavaScriptとmapファイルが生成される。ファイルを指定すると、すべてのTypeScriptのコンパイル結果が1つのJavaScriptとmapファイルにまとめられる。次のsourcemapのところで説明しますが、destは1つのファイルにまとめておくのがおすすめです。sourcemapTypeScriptでデバッグするときには、やっぱりsourcemapを使いたい。TypeScriptのコンパイル結果をそのままHTMLから参照するのであれば特に問題ないのですが、TypeScriptでコンパイルした結果をminifyする場合は、2段階のsourcemapの解決が必要になるのでちょっとややこしくなります。Gruntfileの設定例はこんなかんじになります。}}それぞれのタスクの説明をします。copy:scriptsTypeScriptのファイルをWebサーバから見える場所に置きます。(sourcemapで解決するときに使うので)typescript:mainTypeScriptのコンパイルをして、App.jsとApp.js.mapを生成します。uglify:devApp.jsとAngularJSやその他ライブラリのファイルを結合して、App.min.jsを生成します。sourceMapInオプションでApp.js.mapを指定し、App.min.jsからTypeScriptへのマッピングを解決するためのApp.min.js.mapを生成します。uglifyのsourceMapInオプションは1ファイルしか指定できない(functionを指定すれば指定できる?)ようなので、TypeScriptのコンパイル結果は1つにまとめておくのがよいです。これでChromeやIDEを使って、TypeScriptのソースにブレイクポイントを張ったりできるようになりました!コードの書き方TypeScriptでAngularJSの基本的なコードの書き方は、generator-angularで生成されるコードが参考になります。生成コードのテンプレートはこちら。https://github.com/anchann/generator-angular/tree/typescript/templates/typescript基本は上記のコードを見れば分かると思うので、ここでは応用的な書き方について紹介したいと思います。ScopeとControllerまずは、ScopeとControllerの書き方を3種類紹介したいと思います。説明のためにController内にビジネスロジック的なものを書いていますが、ちゃんとしたコードを書くときはビジネスロジックはModelに書くようにしてください。基本的な書き方IScopeを継承した新しいinterfaceと、Controllerクラスを定義します。JavaScriptと比べるとScopeの定義を書くのが面倒に感じるかもしれませんが、型チェックで得られるメリットは大きいので我慢して書きます。}}Viewに公開するメンバ関数はコンストラクタの中で定義するので、コンストラクタは長くなりがちです。Viewに公開したくないメンバ変数やメンバ関数は、Controllerクラスのprivateメンバとして用意します。angular.bindを使うControllerのメンバ関数をangular.bindを使ってScopeにバインドする方法です。}}bindを書く手間はありますが、コンストラクタがだらだらと長くなることはなくなりました。Syntaxを使った方法です。}}ScopeとControllerがまとまって、すっきりと書くことができました。HTML側の書き方が少し変わるので注意が必要です。この書き方は、ScopeとControllerの役割分担ができないとか、ViewからControllerの中がすべて見えてしまう(privateつけても呼び出せる)とか、問題点を指摘されたりもしているので、採用する際には少し検討したほうがよさそうです。interfaceを実装することもできます。interfaceを使ったほうが型のサポートがあるので安心ですね。IDirectiveのメンバ関数やメンバ変数には?がついているので、必要のないメンバ関数・メンバ変数は実装しなくても大丈夫です。app.directive.MyDirective());$resourceへのメンバ関数の追加サーバーサイドと通信するための$resourceサービスは、標準でGET、POST、DELETEのHTTPメソッドが使えるようになっています。それ以外のHTTPメソッド(PUTなど)を利用したい時は、自分で新しいメンバ関数を追加することになります。TypeScriptでは新しいメンバ関数を追加しても、呼びだそうとすると「そんな関数知らないよ」とコンパイル時に怒られてしまいます。そこでまず、IResourceClassを継承して、新しいメンバ関数を追加したinterfaceを用意します。}}続いて、PUTメソッドを追加した$resourceを返すサービスを用意します。});コントローラにそのサービスを渡してあげます。}]);これで、PUTメソッドを追加した$resourceを、Controllerから使えるようになりました。$resourceのメンバ関数はany型の引数を渡せるようになっているのでちょっと頼りないですね。厳密に型チェックをしたいのであれば、ちゃんと引数や戻り値の型を定義したクラスを別途用意して$resourceをラップしてしまいましょう。まとめ一度TypeScriptで書き始めると、もう生JavaScriptは書きたくなくなります。upLoginユーザーは見つかりませんでした。