TypeScriptの型定義ファイルを共有しよう！

2014/11/13 改訂 CONTRIBUTORS.mdが自動生成になった

こんにちは、株式会社トップゲートのわかめ([@vvakame](twitter.com/vvakame))です。
TypeScript 1.0がリリースされ、大変喜ばしい限りです！
安定版がリリースされたので、これから普及にはずみが付くでしょう。

TypeScriptはJavaScriptのスーパーセットです。
そして、TypeScriptは静的型付け言語です。
ところが、JavaScriptは動的型付け言語なんですね。なので、JavaScriptの既存ライブラリをTypeScriptで安全に使うには、型情報を後付で与えなければなりません。
それが、型定義ファイル(言語仕様上はdeclaration source file)と呼ばれるものです。

この型定義ファイルを集積しているサイトが、[DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped)になります。
DefinitelyTypedはMicrosoftの公式ブログでも[言及](http://blogs.msdn.com/b/typescript/archive/2014/01/02/10472084.aspx)されています。

筆者はしばらく前から[DefinitelyTypedチーム](https://github.com/orgs/DefinitelyTyped/members)に参加させてもらっていて、主にDefinitelyTypedリポジトリのテストインフラのメンテやpull requestのレビューや取り込みを行っています。

そこで、DefinitelyTypedへのpull requestの送り方を解説し、日本からのコントリビュートを増やそうという目論見なわけです。

## 型定義ファイルを使おう

[DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped)からお望みのものを探して普通にダウンロードして使います。
ページを開いて、tキーを押すと絞込検索ができるモードになるので、好きなライブラリ名を入力してみてください。
有名どころはたいてい見つけることができるはずです。

ある型定義ファイルが別の型定義ファイルを参照している場合があります。

例えば[jqueryui.d.ts](https://github.com/borisyankov/DefinitelyTyped/blob/master/jqueryui/jqueryui.d.ts)は[jquery.d.ts](https://github.com/borisyankov/DefinitelyTyped/blob/master/jquery/jquery.d.ts)に依存しています。
このため、jqueryui.d.tsを使いたい場合、jquery.d.tsも併せてダウンロードする必要があります。

ダウンロードした型定義ファイルの保存先はtypingsフォルダを作成し、そこに入れておくパターンが主流派になってきました。
jquery.d.tsとjquery.d.tsの関係を変えないように、例えば以下のように配置して使います。

```
.
└── typings
    ├── jquery
    │   └── jquery.d.ts
    └── jqueryui
        └── jqueryui.d.ts
```

手でダウンロードするのがめんどくさい場合、[tsd](https://github.com/DefinitelyTyped/tsd)を使いましょう。
npmやbowerとサブコマンドの体系が結構違うので、よくREADMEを読むようにしてください(誰か日本語の紹介記事書いてー)。

先の作業と同等のことをするには`tsd query jqueryui --resolve --save --action install` を実行します。
これで、jquery.d.tsとjqueryui.d.tsが上記の構造を保ったままダウンロードされます。

## 型定義ファイルを作ろう

詳しく解説するのがめんどくさいので型定義ファイルを自分で作る方法は詳しくは解説しません。
DefinitelyTypedに既にある型定義ファイルを見てなんとなく察しましょう。

ざっくり書くと、モジュールやクラスや関数や変数を宣言する時にトップレベルの要素には`declare`キーワードをつけるだけです。
もしくは、普通にTypeScriptでガワだけ書いて、`tsc --declaration hoge.ts`とかやるとhoge.d.tsが生成されるので、それをベースに作るのが楽で良いでしょう。

どうにも困ってしまったら、Twitterの[#typescriptjp](https://twitter.com/search?q=%23typescriptjp&f=realtime)ハッシュタグとかに放流しておくとサポートが得られるかもしれません。

## pull requestを送ろう

作った型定義ファイルは積極的にDefinitelyTypedリポジトリにpull requestを送りましょう。

GitHubの使い方がわかっていて、英語も読める人向けには一言、[How to contribute](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute)読んで、それから出してね。でOKです。

まずは、GitHubの使い方がわかっていて、英語は得意じゃない人向けの解説を書きます。

### pull requestを送る前のチェックポイント

注意書き：この解説は[2014年04月04日時点](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute/4ff2e19a7d09e321b0b57922c66904e7544b57cf)のWikiをベースに書かれています。
直訳ではなく、わかめの感じているベストプラクティスを書きます。

#### 新規に型定義ファイルを追加する場合。

##### [バージョン](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#version)

ライブラリの最新バージョンだけメンテされるので、特にファイル名にバージョン番号を含めたりはしません。
これは、ライブラリの複数バージョンをメンテし続ける体力がコミュニティにないからです。
ていうか誰もやりたがらないよねそんなの。

##### [ヘッダをつける](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#header)
  * 型定義ファイルの先頭にはヘッダをつけてください。

```
// Type definitions for [LIBRARY NAME]
// Project: [LIBRARY URL]
// Definitions by: [AUTHOR NAME] <[AUTHOR URL]>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
```

実際の例はこんな感じ

```
// Type definitions for Backbone 0.9.10
// Project: http://backbonejs.org/
// Definitions by: Boris Yankov <https://github.com/borisyankov/>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
```

##### [ライブラリを置く場所](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#location)

jQueryというライブラリの型定義ファイルであったら、 jqueryフォルダを作り jquery.d.ts という名前で置く。

##### [JSDoc書く](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#documentation)

頑張って書きましょう。でも、わかめはJSDocが有効活用できる環境で作業してないのであまり重視してない…＞＜ こんなコト書いたら怒られそうだな。

##### [テストを書こう](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#tests)

型定義ファイルについてテストを書きましょう。良いドキュメント代わりにもなります。
hoge.d.tsという型定義ファイルを作った場合、hoge-tests.tsというファイルを作成し、hoge.d.tsの利用例を書いてください。
hoge-tests.tsが"動作"するコードである必要はありません。コンパイルが通ることが確認できればよいです。

DefinitelyTypedリポジトリは、Travis-CIでテストされています。あなたの型定義ファイルは--noImplicitAnyオプション付きのtscでのコンパイルが成功する必要があります。

ようするに、pull request出す前に `tsc --noImplicitAny hoge/hoge.d.ts` と `tsc --noImplicitAny hoge/hoge-tests.ts` が通ることを確認しましょう。

##### [名前空間の使い方について](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#namespacing)

他のライブラリとコンフリクトしないように、内部モジュールを上手く使おう。

##### ~~[README.mdに名前を書こう](https://github.com/borisyankov/DefinitelyTyped/wiki/How-to-contribute#readme)~~

~~[README.md](https://github.com/borisyankov/DefinitelyTyped/blob/master/README.md)に名前を追加します。~~
~~書式は`* [LIBRARY NAME WITH LINK] (by [AUTHOR NAME WITH LINK])`です。既存のを真似して書いてみてください。~~

CONTRIBUTORS.mdに名前を追記してもらう運用でしたが、毎回指摘するのがいい加減めんどくさかったので[半自動生成にしました](https://github.com/borisyankov/DefinitelyTyped/pull/3079)。
#### 既存の型定義ファイルを修正する場合。

とりあえず--noImplicitAnyオプション付きでコンパイルが通ればOKです。
影響するファイルが大きそうな場合、`npm update && npm run all`で1件もコケなければ大丈夫です。

### pull requestを送る時のチェックポイント

DefinitelyTypedにpull requestを出す時には英語を使います。

しかし、コミットに含まれる変更点がしっかりしていれば、pull requestを送る時のタイトルや概要は超適当でも大丈夫です。
極論をいうと、型定義ファイルを新規追加した場合は`add hoge/hoge.d.ts`というタイトルで概要空欄、更新の場合は`update hoge/hoge.d.ts`とかいうタイトルで概要空欄、で問題ありません。

レビューする時に役に立つので、既存の型定義を修正する場合は、変更点が本当に正しいことが確認できるようなドキュメントやソースコードのURLがついていると嬉しいですね。
無くてもこちらで調べるのでなくてもOKです。

もし、議論に発展した場合は、Google翻訳を活用して頑張るか、GitHub上で`@vvakame`と書いて僕を呼び出して貰えれば僕も一緒にGoogle翻訳を使うのを手伝います :P

### pull requestを送った後のチェックポイント

pull requestを送ると、Travis-CIが自動的に検知してテストを実行します。
その結果、失敗して赤くなる場合があるため、pull requestを送った後しばらく待ってからページをリロードして結果を確認するとよいでしょう。
みなさんがpull requestと送った場合、mergeする権限がないので以下のスクリーンショットとは少し違った状態で表示されると思いますが、参考にはなるでしょう。

Travis-CIが反応する前。
![Travis-CIが反応する前の状態](https://qiita-image-store.s3.amazonaws.com/0/13283/317f7a38-c762-5480-e9a1-4661e79cc9d4.png "pr-before-travis.png")

Travis-CIが反応してテストしている最中。
![Travis-CIが反応してテスト中の状態](https://qiita-image-store.s3.amazonaws.com/0/13283/79cfca14-dd85-ad0e-5b70-6fab8505e338.png "pr-processing-travis.png")

Travis-CIでのテストが成功した状態。
![Travis-CIでテストが成功した状態](https://qiita-image-store.s3.amazonaws.com/0/13283/4ecd03e6-3b31-921f-e195-f2cc880f8bf1.png "pr-after-travis.png")


あとは、レビューされてマージを待つだけです！
テストが失敗したり、レビュワーから指摘があった場合、追加のコミットを作成して、同じブランチにpushすれば自動的にpull requestにも反映されます。
pull requestを作り直す必要はありません。

### GitHubでのpull requestの作り方

forkして、適当に新しくブランチ切ってコミット作って、forkした自分のリポジトリにpushします。

GitHub上で適当にブランチが増えていることを確認しましょう。
![pushしたらブランチ増えるね！](https://qiita-image-store.s3.amazonaws.com/0/13283/e91312e6-7f41-beda-4a29-7773d0e40f31.png "create-new-branch.png")


リポジトリのトップページに、pull requestを送るUIが出現しているはずです。
![ガッツリ押そう](https://qiita-image-store.s3.amazonaws.com/0/13283/a745a132-331d-69f0-bf50-d033cf8bb7bb.png "send-pull-request.png")


送信前の変更点の確認を行いましょう。
![タイトルとコメントは適当だ！](https://qiita-image-store.s3.amazonaws.com/0/13283/c28914fb-dd9e-0df4-a1db-a7ab9d6572aa.png "comfirm-send-pull-request.png")


## 最後に

では、よいTypeScriptライフを！

GitHubについてもっと知りたい場合は、最近出た[GitHub実践入門](http://www.amazon.co.jp/gp/product/477416366X?tag=damenako-22)という本が評判が良いとの噂です(僕は立ち読みしかしてないですが :P)。