読者です 読者をやめる 読者になる 読者になる

【はてなスタッフ非公式ブログバトン】TypeScript のすゝめ

id:hitode909 さんからバトンが回ってきたので、TypeScript いいよね、っていう話をする。

TypeScript

TypeScriptC# を作ってる人が作ってるという altJS 。言語の特徴とかは wikipedia 、勉強するときは TypeScript クイックガイド を見るのが良いと思う。JavaScript 書ける人にとっては学習コストは比較的低めと思う。

簡単にいうと ECMAScript 6 を一部先取りして型アノテーションをプラスしたもの。自分が altJS 選ぶ時に基準にしたのが以下の二つで

  • 静的な型チェックがある
  • 導入・離脱が容易

この二つの要求にもっとも合致するのが TypeScript だった。特に後者は「プログラミング言語」として語られると軽視されがちだけど実用上とても重要だと思う。

静的な型チェックのうれしさ

特に説明しなくてもいいかもしれない。「機械が型をチェックしてくれる」のがうれしくない人はいないはず。

TypeScript の場合はけっきょく JavaScript になってしまうので、静的型付と言ってもパフォーマンスが上がったりはしないけど、特にリファクタリングのときに型チェックがあるのとないのとでは開発効率が全然違う。

適切に(この"適切"が議論の種なのだけども)型がついていれば、例えばリネームとかメソッドを別のクラスに移動するとかは安心してできる。IDE使ってれば機械でできるかもしれない。

JavaScript は柔軟な言語で、ブラウザですぐ実行できるし簡単にUIがいじれる(目に見える)ので、とりあえず動かすっていうところまですぐに辿り着けてやる気がでる。あふれるやる気に身を任せてコード書く

_人人人人人人人人人人_
> 突然のクソコード <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

とすぐに汚くなるのでリファクタリングが重要だし、それがやりやすいのはとてもうれしい。

オプショナルな型アノテーション

TypeScript の型アノテーションの良いところはそれがオプショナルで、柔軟に型付けすることができることだと思う。 型アノテーションをつけないこともできるし、型チェックが通らなくてもコンパイルはできるので、静的型付言語はガシガシコード書けなくて開発効率下がるという人も安心して開発できる。

もちろんこれはデメリットでもあって、全然型安全じゃないし安心できないっていう人もいると思う。この辺は結局ガシガシ書きたい気持ちと安心したい気持ちのバランスをどうとるのかっていう問題になる。

TypeScript はその辺り開発者が幅をもって選択することが出来て、例えば

  • ライブラリはきっちり型をつける
  • アプリケーションのModel層ではしっかり型を付け、Controller層ではすこし緩くする

っていうこともできる。

個人的にはメソッド・関数の引数・返り値とクラスのフィールドにちゃんと型を付ければ(ある程度型推論もあるので)アプリケーションのコードではけっこう事足りるし、書きたい気持ちも阻害されない。 クライアント側は比較的バグっても致命的になりにくいし、厳格に型を付けるのはコストが高いかなと思う。 総じてバランスがよいと思う。

導入・離脱の容易さ

新しくプロジェクト作るぜっていうときは良いけど、現実には既に書かれた大量の JavaScript コードがある。ほらあなたの目の前にも。ロジックは同じとはいえこれを別の言語に全部かきかえるっていうのは結構骨の折れる作業で、やりたくない。ファイル単位でaltJS導入するっていうのも出来るだろうけど、それもあんまりやりたくない。

TypeScript は JavaScript のスーパーセットなので、極端な話、拡張子を js から ts に変更してコンパイラに渡してやればコンパイルできる。(エラーいっぱい出るけど。)

$ mv hoge.js hoge.ts
$ tsc hoge.ts

これで一応導入完了。あとはコツコツ型を付けたりオレオレクラスを TypeScript のクラスに書き換えたりアロー関数式つかったりしていけばいい。そもそもロジックの部分はほとんどそのままなので、書き換える部分が少ない。 前に Backbone で書いたコードを TypeScript に書き直したら、手で愚直にやっても一日 1000 行くらい書き直せた。いいツールがあればもっとさくっと行くと思う。

既存の JavaScript のライブラリもそのままつかえる。そのライブラリが TypeScript で書かれてなくても、型を別に定義することができる。GitHub に 型定義ファイル集めるリポジトリ があって、有名なライブラリはけっこうそろっている。型定義ファイルをローカルにインストールする tsd というコマンドもあって tsd install jquery のように使える。 ここに型定義がなかったときは自分で型定義するか、そのライブラリの型チェックを諦めてもいい。型定義のしかたは上のクイックガイドを見てもらうとして、無視する場合は

declare var Hoge:any;

とかすると、Hoge に何してもコンパイルで怒られることはなくなる(かわりに型の恩恵もうけられない)

ただし、TypeScript の機能とライブラリが競合する場合(独自にクラスを実装をしているライブラリとか)には工夫が必要。Backbone.View の場合は以下の感じで動いたけど、それぞれどんな実装かによって対応を変える必要がある。この辺は面倒。

class Hoge extends Backbone.View {
    model: Model.Hoge;
    template: (...args: any[]) => string;
    constructor (options?: Backbone.ViewOptions) {
        this.tagName = 'li';
        this.className = 'class';
        this.events = {
            'click .item' : (event) => this.onClickItem(event),
        };
        super(options);
        this.template = JST['thread-tab-item'];
        this.listenTo(this.model, 'change', this.onChangeModel);
    }
    ...
}

離脱

TypeScript をおすすめする理由として、TypeScript は辞めやすいっていうのを挙げるのもどうかと思うけど、大事なことだと思う。

TypeScript が吐き出す JavaScript はかなり綺麗で、自分はデバッグするときも特に SourceMap とか使ってない。 Playground で試すことが出来るので試してみてほしい。 あとコンパイラ-c オプションを渡すとコメントも全て残すことができる。なので TypeScript 廃れたらコンパイルされた JS を保守していけば良い。

そもそも TypeScript の仕様のほとんどが ECMA6 のものなので、そのうち JavaScript に実装される(ハズ...)そうなったら TypeScript は型アノテーションを処理するだけになるので、吐き出される JS との差分もより少なくなる

その他メリット

class, module, アロー関数式とかあって便利なのは他の altJS とだいたい一緒だと思う。 その他、静的に型がついてるのでコード補完が効くとかあると思うんだけどちょっと手を出せていない。

デメリット

JavaScript そのまま使うのにくらべると、コンパイルの手間と学習コスト、廃れるリスクっていうデメリットがある。

他の altJS(あまり知らないけど) と比べると、Coffee ほどタイプ数減らない、Haxe ほど型が強力じゃない、JavaScript の悪いところが悪いところのままになってたりする、主な IDE が VisualStudio で Mac に入れられない(WebStorm が使える?)とかが挙げられる。

あと吐き出されるJSの改行コードがCR+LFになる。オプションとか見つからなかった。

まとめ

JavaScript は altJS というより betterJS という感じで、コンパイルの手間が許容できるなら、JavaScript より TypeScript 使ったほうがいい。 ブラウザのUIを書く用途では TypeScript くらいの型付けがバランスがよい。 かなり贔屓目になっているけど、業務に使うなら CoffeeScript よりは TypeScript だと思う。理由は

  • CoffeeScript で得られるメリットはだいたい TypeScript でも得られる(Lint, クラスベース, アロー関数式, SourceMap)
  • JavaScript 互換なので比較的 学習・導入コストが低く、廃れたときのリスクも低い
  • 型チェックの恩恵を受けられる

(とはいえ結局はケースバイケースで、Coffee がいいプロジェクトも当然あると思う。とか防衛的なコメントつけておく)

次回

明日は id:tarao さんが dart か Haxe か何かについておもしろい話をしてくれます

こっち -> http://d.hatena.ne.jp/tarao/20131212/1386859873