TypeScriptを書く前に押さえておきたい型定義の扱い。またはtsdを投げ捨てる理由

TypeScriptはめぐるめくときめきの言語なのですが、型定義ファイルをどう扱うかに暫く頭を悩まされていました。型定義をnpmのごとく集めてきてくれるツールもあるのですが、型定義が間違っている場合もあり、自分で直すとするとそのバージョン管理はどうするんだーとなり、かえって面倒になります。
TypeScriptを扱ううえで型定義ファイルは欠かせません。ここでは型定義ファイルを自分で編集することを踏まえた扱いについて考えてみました。

型定義、大事
====

TypeScriptは型情報を備えた言語です。しかも強力な型推論を持っていて、関数の引数以外は意識して型を書かなくてもモリモリ型情報がくっついてくれます。
張り巡らされた型情報は、コンパイル時やコーディング中、関数やメソッドを間違えて使っていれば叱ってくれますし、Visual StudioやWeb StormなどのIDEなら使えるメソッドなどをサジェストして開発者を助けてくれます。
勿論JavaScriptの標準ライブラリを使用する際にもガンガンサジェストしてきます。これは、標準ライブラリ用の型定義がコンパイルに組み込まれているからです。
外部ライブラリを使用する際も、たとえTypeScriptで書かれていなくとも、型定義ファイルを用意することによってライブラリが持つ変数や関数、クラスなどに型情報を与えることができます。
ライブラリの型定義ファイルはコミュニティーによってかなりの数が揃えられています。

[borisyankov/DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped "borisyankov/DefinitelyTyped")

ビルドの基本事項
====

いざTypeScriptを本気で使おうとすると、ビルドツールはほぼほぼ必須になります。Visual Studioの標準のビルド機能では貧弱すぎますし、用途も限られます。（JetBrain系のIDEは詳しくありません）
なので、html系全般に強いnode.js製のGruntやGulpといったビルドツールを用いてビルドを行います。

GruntやGulpなどの詳しい説明はここでは省きますが、必要ならこれらの記事を読むといいでしょう。
[ビルドツールまとめ。Gruntとかgulpとか (フロント寄り) - Qiita](http://qiita.com/cognitom/items/db88babebeb869a4a198 "ビルドツールまとめ。Gruntとかgulpとか (フロント寄り) - Qiita")
[grunt-typescript](https://www.npmjs.org/package/grunt-typescript "grunt-typescript")
[gulp-typescript](https://www.npmjs.org/package/gulp-typescript "gulp-typescript")

型定義ファイルを集める便利なツールたち
====

型定義ファイルはどのように入手すればいいでしょうか？
前述のように、TypeScriptの型定義ファイルはコミュニティによって揃えられています。
tsdやdtsmなどは、npmやbowerのように型定義ファイルを自動的にプロジェクトに追加することが出来るツールです。GruntやGulpなどのビルドツール向けのプラグインもちゃんと用意されています。

| 型定義ファイル管理                                | ビルドツール向けプラグイン                                                                                                     |
|---------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| [TSD](http://definitelytyped.org/tsd/ "TSD")      | [grunt-tsd](https://www.npmjs.org/package/grunt-tsd "grunt-tsd")<br>[gulp-tsd](https://www.npmjs.org/package/gulp-tsd "gulp-tsd") |
| [dtsm](https://www.npmjs.org/package/dtsm "dtsm") | [grunt-dtsm](https://www.npmjs.org/package/grunt-dtsm "grunt-dtsm")                                                            |


**だがちょっと待ってほしい**。最初に述べたように、TypeScriptの型定義ファイルはまだまだ品質に難があり、これらのツールを使って型定義ファイルを集めると困ったことになります。
npmやbowerに例えると、せっかく集めたライブラリにしょっちゅう手を加えなければならないということです。

Git Submoduleで全部取ってくる作戦
====

ここでは**GitのSubmodule**を用いて、型定義ファイルのプロジェクトをまるごと自分のプロジェクトに含めてしまう方法をお勧めします。

なお、Submoduleについてはこちらをどうぞ。
[Git submodule の基礎 - Qiita](http://qiita.com/sotarok/items/0d525e568a6088f6f6bb "Git submodule の基礎 - Qiita")

すべきことは3つです。
1. [borisyankov/DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped "borisyankov/DefinitelyTyped")をForkする
2. 自分のプロジェクトの*typings*ディレクトリにforkしたDefinitelyTypedプロジェクトをsubmodule addする
3. 必要に応じて、DefinitelyTypedプロジェクトにブランチを作成する

こうすることで、**自身で作成、修正した型定義をバージョン管理**できますし、**必要な型定義ファイルを選択して導入する**という手間も省けます。

コマンドを記載します。（先にGithubで[borisyankov/DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped "borisyankov/DefinitelyTyped")をForkしてください）

```shell-session
$ git init
$ git submodule add https://github.com/【あなたのユーザー名】/DefinitelyTyped typings
$ cd typings
$ git remote add upstream https://github.com/borisyankov/DefinitelyTyped
$ cd ..
```

これで、あなたは型定義ファイルを自由に編集することが出来るようになりました。実際にコードを書いて、おかしいと思う型定義があれば、ライブラリのドキュメントとにらめっこの上、型定義ファイルを直してしまえばいいのです。

型定義ファイルを書く
====

型定義をどう書けばいいかは、実際に型定義ファイルを見て徐々に察しましょう。あるいはこれらの記事が役に立つかもしれません。
[TypeScript - Documentation](https://typescript.codeplex.com/wikipage?title=Writing%20Definition%20%28.d.ts%29%20Files "TypeScript - Documentation")
[Best practices | DefinitelyTyped](http://definitelytyped.org/guides/best-practices.html "Best practices | DefinitelyTyped")

そして折角型定義ファイルを直したのであれば、是非とも公式のリポジトリにプルリクエストを出しましょう。

[TypeScriptの型定義ファイルを共有しよう！ - Qiita](http://qiita.com/vvakame/items/1980d4b6cc222e03fdcb "TypeScriptの型定義ファイルを共有しよう！ - Qiita")

まとめ
====

* 型定義ファイルは大事だけど実際のライブラリと合ってないと意味をなさない
* tsdなどで型定義ファイル取って来ると自分で編集したくなった時に困る
* Gut Submoduleを使うと型定義ファイルの取得、管理、公開が楽

他にも読んでおきたい記事
====
* [Node.js - Gruntfile.js が長すぎてつらい人は gulp を使ってみよう - Qiita](http://qiita.com/shuhei/items/4aaa550d1ad30d2fc3b5 "Node.js - Gruntfile.js が長すぎてつらい人は gulp を使ってみよう - Qiita")
* [VisualStudio - Visual StudioでGrunt(Task Runner Explorer) - Qiita](http://qiita.com/k_maru/items/e00298b5f132ea200395 "VisualStudio - Visual StudioでGrunt(Task Runner Explorer) - Qiita")