これは TypeScript Advent Calendar 2014 の11日目(12/11)の投稿です。
TypeScirpt、これは単純に優れているのではと思い、この機に試してみました。今回は薄いフレームワーク(ライブラリ)として私が勝手に重宝している Knockout.js に TypeScript を適用してみます。
尚、事前準備となる周辺環境(WebStorm、TypeScript本体、TSD)については昨日こちらに書いたので、宜しければ参照ください。
→ WebStorm で TypeScript を始めよう!
まずは Knockout.js の環境構築
Yeoman でサクりと作っちゃいます。
今回の前提環境
yo:
1.3.2
generator-webapp:0.5.1
Knockout.js:3.2.0
jQuery:2.1.1
手順
Yeoman の generator-webapp を起動し、適当に Bootstrap のみを選択します(まあ何でもいいのですが)。
$ yo webapp
次に、Bower で Knockout.js をインストールします。
$ bower install knockoutjs --save
このバージョンのジェネレータで作成されるプロジェクトでは、次のコマンドで index.html
に必要なものが自動で追記されるので、コマンドを叩きます。
$ grunt wiredep
結果的に、次のように追記されました。jQuery も入っていますね。
<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/knockoutjs/dist/knockout.js"></script>
<!-- endbower -->
<!-- endbuild -->
まずはこの状態(TypeScriptを導入しない状態)で、Knockout.js の動作確認をしてみます。View を次のように書き、
<p>名:<input data-bind="value: firstName, valueUpdate: 'afterkeydown'"></p>
<p>姓:<input data-bind="value: lastName, valueUpdate: 'afterkeydown'"></p>
<h4>フルネームは <span data-bind="text: fullName"> </span></h4>
ViewModel を次のように書きます。
$(function() {
var ViewModel = function(first, last) {
this.firstName = ko.observable(first);
this.lastName = ko.observable(last);
this.fullName = ko.computed(function() {
return this.lastName() + " " + this.firstName();
}, this);
};
ko.applyBindings(new ViewModel("太郎", "山田"));
});
$ grunt serve
でブラウザを開き、データバインドが動いていればOKです。
型定義ファイルの導入
昨日の投稿(WebStorm で TypeScript を始めよう!)にも書きましたが、このプロジェクトに jQuery と Knockout.js の型定義ファイルをインストールします。
$ tsd init
$ tsd query jquery knockout --action install --resolve --save
以降は TypeScript ファイルの冒頭で、次のように型定義ファイルを指定すればOKです。
/// <reference path="../../typings/tsd.d.ts" />
Knockout.js を TypeScript で書いてみる
いったん、元の app/scripts/main.js
は削除し、app/scripts/main.ts
を作成します。WebStorm のウオッチャーにも追加しておきます。
ここまでで、プロジェクトは次のようになっているハズです。
View を書きます
こちらは普通に。
<p>名前:<input data-bind="value: name, valueUpdate: 'afterkeydown'"></p>
<p>年齢:<input data-bind="value: age, valueUpdate: 'afterkeydown'"></p>
<p>あなたは <span data-bind="text: name"></span> さん、<span data-bind="text: age"></span> 歳 ですね!</p>
ViewModel を書きます
あまり TypeScript 分かってないので.. それっぽく書きます。name
は文字列型(string)、age
は数値型(number) という風に型を定義しました。
/// <reference path="../../typings/tsd.d.ts" />
class HogeViewModel {
// 何も指定しないと public になる
private name: KnockoutObservable<string> = ko.observable('');
private age: KnockoutObservable<number> = ko.observable(0);
constructor(name: string, age: number) {
this.name(name);
this.age(age);
}
}
$(function() {
ko.applyBindings(new HogeViewModel('山田', 32));
});
コンソールで $ grunt serve
し動作確認します。
型チェックやコード補完の具合を見てみる
※ 上にも書きましたが、IDE は WebStorm を使っています。
Knockout.js のコード補完が効いています。
もちろん、TypeScript のコード補完も効きます。
型エラーは、リアルタイムにチェックされます。
ちなみに型定義ファイルを指定しないと、こんな感じでエラーになります。
コンパイル後の .js
ファイルを見てみる
こんな感じで変換されています。綺麗に読める感じ。
ちなみに型チェックがある JavaScript コードが吐かれるわけではないです。
おわりに
まだ導入の域を出ないですが、Knockout.js を TypeScript で書く手順を紹介しました。
TypeScript の静的な型システムは強力なので、これから自分的に試していきたいな、と思っています。
今回のソースはこちらに置きました。
→ https://github.com/hkusu/Knockout.js_TypeScript_sample
(.js
ファイルや型定義ファイルはもしかして commit しない流儀なんだろうか? よくわからず。)