この記事は、Angularをテーマとした日本初のカンファレンス 「ng-japan」のイベントレポート(第4回目)です。
はじめに
昨年秋に、Angular 2はAtScriptというaltJSで開発するといったアナウンスがありました。しかし、今年3/5に急遽、Angular 2はTypeScriptで開発するという変更がなされました。このニュースはGoogle社とMicrosoft社が手を結んだということでも大きなニュースになり、今年一番の出来事かもしれません。
そのTypeScriptとカレントバージョンであるAngular 1.3を利用した開発ポイントを、株式会社トップゲートのエンジニアであり、TypeScriptマスターでもある@vvakame氏に講演していただきました。
TypeScript+Angular 1.3 – vvakame
AtScriptからTypeScriptに移行される旨がアナウンスされたため、TypeScript自体の話を少しと、現行のAngular 1.3とTypeScriptを組み合わせて開発する方法についてお話します。
「AtScriptの近況と将来」の話をしようと思いましたが、3月頭に必要なくなったようなのでタイトルを変えました。「TypeScript+Angular 1.3」というタイトルでお話させていただきます。
Angularを取り巻く開発言語
ECMAScriptとは
ECMAScriptに関して整理します。
- JavaScriptの元となる仕様のこと
- DOMの仕様は入っていない
- 最近のブラウザはECMAScript 5をサポート
- そろそろ6の仕様が確定(現在RC2
AtScriptとは
AtScriptとは何だったのかを振り返ってみます。
- AtScript=ES6+A (A=Annotiosion, AnnotationはES6に含まれない)
- Super set of TypeScript
AngularチームがAngular 2を開発するために策定したTypeScriptより、優れているaltJSということでした。
TypeScriptとは
では、TypeScriptの特徴はどういうものかを整理します。
- TypeScriptはJavaScriptを拡張した言語
- 静的型付け
- ECMAScript6規格の文法を取り込み中
- 読みやすい変換後JavaScript
- Java, C#とかにやさしい言語仕様
TypeScriptは、Microsoftが出してきたということで当時注目されました。特徴の一つである静的型付けの特徴をまとめます。
- 静的解析で多くの整合性検証が可能
- 不整合があった場合、コンパイルエラー
- 大規模、大人数になるほど有利
- Java, C#が有名
通常のJavaScriptでは、バグに関して実際に動かしてみて初めて分かりますが、TypeScriptのような静的型付けを用いると、静的解析でより多くの整合性検査が可能です。なるべくコンパイルした段階で、エラーが出力されるところが良い点の一つです。
例えば次の文はエラーになります。
var foo: number="bar";
TypeScriptは、ECMAScript 6のスーパーセットになると考えられています。既存の資産を活用したいという要望も当然あります。そうした要望を満たすため、TypeScriptに様々なJavaScriptライブラリの型を定義した型情報を用意する必要があります。例えば、次のようなものがあります。
- jQuery
- Angular
- mocha
- etc
DefinitelyTyped
型定義ファイルというものがあります。現在は1,000個以上あります。既存JavaScriptに型を後付けというのはわかりづらいとは思います。
Angularの例を見てみます。
declare var angular: angular.IAngularStatic;// Type definitions for Angular JS 1.3+ // Project: http://angularjs.org // Definitions by: Diego Vilar // Definitions: https://github.com/borisyankov/DefinitelyTyped
///
declare var angular: angular.IAngularStatic;
// Support for painless dependency injection interface Function { $inject?: string[]; }
// Collapse angular into ng import ng = angular; // Support AMD require declare module 'angular' { export = angular; }
/////////////////////////////////////////////////////////////////////////////// // ng module (angular.js) /////////////////////////////////////////////////////////////////////////////// declare module angular {
// not directly implemented, but ensures that constructed class implements $get interface IServiceProviderClass { new (...args: any[]): IServiceProvider; } interface IServiceProviderFactory { (...args: any[]): IServiceProvider; } // All service providers extend this interface interface IServiceProvider { $get: any; }
実際にこれを使ってコードを見てみます。JavaScriptとあまり変わりがないので読みやすいのではないかと思います。
module App { "use strict";angular.module( "app", ["ngRoute", "app.hello"], ($routeProvider: ng.route.IRouteProvider, $locationProvider: ngILocationProvider)=> { $routeProvider .when("/sample", { templateUrl: "/template/sample.html" }) .otherwise({ templateUrl: "/template/main.html" }); $locationProvider.html5Mode(true); } ) .run(($rootScope: ngIRootScopeService, $routeParams: ng.route.IRouteParamsService)=> { false; }) ; angular.module( "app.hello", [], ()=> { false; } ) .service("sampleService", Service.SampleService) .controller("SampleTestController", Sample.TestController) ;
Angular 2とTypeScript
2015年3月5日に、Angular 2はTypeScriptで作ることになるという記事が出てきました。AtScriptからTypeScriptに変えた理由がいくつかあり、AngularチームとTypeScriptチームの調整がうまくいったのではないかと考えられます。
- TypeScriptに必要な機能が入る
- Angularチームが作りたいのは、AtScriptではなくAngular本体である
- TypeScriptのスーパーセットを作るのが困難
TypeScriptのスーパーセットを作るという話でしたが、TypeScript自体の開発スピードがかなり早く、しかもその間にECMAScript 6の仕様も出て、短期間の内にAtScriptを開発するためには、人的にもコスト的にも難しい状況だと考えられます。
話をまとめると、Angularを使うという観点からも、今からTypeScriptを使う必要があると言えます。
TypeScriptのSyntax
TypeScriptの独自Syntaxはあまりなく、JavaScriptとそれほど変わるものではありません。TypeScriptですが、だいたい2日もあれば書けるようになると思われます。
Type Annotations
Type Annotationsを具体的に見てみます。
var str1:string = "string"; var str2:number = "string"; // エラー var str3 = "string"; // 初期化子から型推論されstringを指定したのと等価 str3 = 1; //エラーvar b: boolean = true; var n: number = 1;
var a: any = true; a = 1; // anyは何でもOK
Classes
ECMAScript 6からは、クラスの宣言ができるようになりました。TypeScriptの例を見てみます。
class Hoge { name: string;constructor(name: string) { this.name = name; } hello(): string{ return "Hello, " + this.name; }
}
var obj = new Hoge("world"); window.alert(obj.hello());
Interface
TypeScriptで定義したInterfaceは、実行時には消えてしまいます。型だけの定義です。
interface Hoge { str: string; num: number; }var obj: Hoge = { str: "string", num: 1 };
window.alert(obj.str + obj.num); window.alert(obj.hello());
Allow Functions
Allow Functionsは、最近話題になっています。メリットとしては、functionというキーワードが必要なくなるところです。これはECMAScript 6でも標準化されますので、TypeScriptを通して今のうちから慣れるのもよいかと思います。
var hello = (word: string) => console.log("Hello, " + word); hello("TypeScript");// 返り値の型を明示する var hello2 = (word: string): void => console.log("Hello, " + word); // 参考:今まで通りの書き方 1 var hello3 = function (word: string) { console.log("Hello, " + word); }; // 参考:今まで通りの書き方 2 function hello4(word: string) { console.log("Hello, " + word); }
internal modules
今までのJavaScriptでは、モジュールの定義するというのは存在していませんでした。TypeScriptではモジュールが定義されています。今は過渡期でこうした書き方ですが、ECMAScript 6だと書き方があるので、なくなると思われます。
module app { export class Sample { hello(word = "TypeScript") { returnHello, ${word}
; } } } var obj = new app.Sample(); console.log(obj.hello("AngularJS"));var app; (function (app) { var Sample = (function () { function Sample() { } Sample.prototype.hello = function (word) { if (word === void 0) { word = "TypeScript"; } return "Hello, " + word; }; return Sample; })(); app.Sample = Sample; })(app || (app = {})); var obj = new app.Sample(); console.log(obj.hello("AngularJS"));
Generics
Genericsは非常に便利です。
class Container { constructor(public data: T) { } }var a = new Container("str"); var b = new Container(1);
a.data.charAt(0); b.data.toExponential();
はじめてみよう – Angular-typescript
@vvakameのgithubにあるので是非見ていただき、TypeScriptを始めてもらえたらと思います。
開発する際、利用するツールは次の通りです。
- node.js
- grunt
- bower
- TypeScript ** tslint ** typedoc ** dtsm (tsd)
- LESS
- unit test ** mocha ** power-assert
- karma
- protractor
- その他
Angular 1.3と組み合わせる
あまり考えなくてよく、TypeScriptと重ねることは特別なことはないです。TypeScriptはJavaScriptの延長線上にあり、JavaScriptのベストプラクティスがそのまま利用することができます。
その中で覚えなければならないのは
- 型の名前
- 使いたいメソッド(angularのドキュメントを読むより型定義ファイルを見たほうが早い)
- 使いたいDIオブジェクト名
その中で次のことに注意すれば、問題なく記述することができます。
- tsc –noImplicitAny
- 型注釈を書く
CodeIQとの連動企画!
AngularJS雑学、豆知識を問う問題です。腕試しに、もしくは理解度チェックに是非ご活用ください!こちらから問題にチャレンジ!
問題:知ってる?AngularJS雑学
プレゼンテーション資料
今回取り上げたプレゼンテーションの資料は、以下のとおり公開されています。合わせてご覧ください。
セッション動画
当日のセッションはYouTubeで公開されています。是非ご覧ください!