TypeScriptの型定義管理ツールTypingsについて


https://github.com/typings/typings

[tsdが非推奨になった](https://github.com/DefinitelyTyped/tsd/issues/269)ということで新しく推奨されているTypeScript型定義管理ツールの「typings」に関して調べたのでその備忘録。

# Typingsとは
tsdと同じくTypeScriptの型定義ファイルを管理するツールです。

GitHubから型定義を取得してくるしかなかったtsdと違って、npmやbower、githubプロジェクト、ローカルファイルシステムやhttp経由で型定義ファイルを取ってこれるのが特長です。DefinitelyTypedもサポートしているので、tsdから移行して困ることはありません。

また、tsdと違ってGitHubのAPIを叩かないので、[GitHubAPIのrate limitに引っかかって落ちる](https://github.com/DefinitelyTyped/tsd#github-rate-limit)ということもありません。 [^1]

[^1]: ただ、代わりに型定義の検索(search)、新規インストール時(install xxx)には https://api.typings.org/ という[謎API](https://github.com/typings/api)を叩いているようです。このAPIがどれだけ信頼性のあるものなのかは不明ですが、プロジェクトに`typings.json`さえあれば、そこから`typings install`コマンドで型定義を取得する分にはこのAPIは利用しないようなので問題になるケースは少ないかもしれません。

# インストール方法

```
npm install -g typings
```

# 基本的な使い方
tsdコマンドを置き換えるだけならすごく簡単です。

## プロジェクトの初期化
Typingsはプロジェクトディレクトリの`typings.json`ファイル（tsdでいうところの`tsd.json`）にそのプロジェクトが利用している型定義一覧を保存するので、以下コマンドで`typings.json`を作っておきます。

`typings-sample-project`というディレクトリを新しく作ってプロジェクトディレクトリとして試してみる場合は以下のような感じ。

```
mkdir typings-sample-project
cd typings-sample-project
typings init
```

## 何か型定義を新しくインストールする

```
typings install jquery --save --ambient
```

プロジェクトディレクトリの`typings/`ディレクトリに型定義がインストールされます。
実際には`typings/main.d.ts`を`reference path`に追加して使ったりします。

## プロジェクトが利用している型定義をインストールする
cloneしてきたプロジェクトに`typings.json`がある場合は、以下コマンドで必要な型定義をインストールできます。

```
typings install
```

## 型定義を探す

```
typings search jquery --ambient
```

## ambientオプション
Typingsでは何かにつけて`--ambient`というオプションを付けるというか大体のコマンドは付けないと利用できないんですが、意味としてはそのままTypeScriptの「[アンビエント宣言(実装のないインターフェースだけの宣言)](http://www.typescriptlang.org/Handbook#modules-working-with-other-javascript-libraries)」のことらしいですね。

Typingsでは、この`declare module`を直接取り込む際に`--ambient`を指定させるようです。

例えば、Typingsではローカルファイルから型定義をインストールできるので以下のように`.d.ts`ファイルを用意してみます。

```typescript:sample.greeting.d.ts
declare module Greeting {
  export interface Hello {
    message: string;
  }
}

declare module "sample.greeting" { export = Greeting }
```

で、このファイルから型定義をTypingsで取り込むため以下のコマンドを実行してみます。

```
typings install file:sample.greeting.d.ts --name "greeting"
```

すると以下のようなエラーが出るはずです。

```
typings ERR! message Attempted to compile "greeting" as a dependency, but it contains some ambient module declarations ("sample.greeting").
```

このように、アンビエント宣言から型定義を取り込む場合は以下のように`--ambient`オプションを指定する必要があるようです。

```
typings install file:sample.d.ts --name "greeting" --ambient
```

なお、TypingsではDefinitelyTypedはアンビエント宣言のリポジトリのうちの一つという位置づけで、次のようにモジュール名を指定してアンビエント宣言を検索するとDefinitelyTypedが使用されます(sourceがdtとなっているもの)。

```
% typings search redux --ambient
Showing 13 results...

NAME                        SOURCE  HOMEPAGE                                               DESCRIPTION
react-redux                 dt      https://github.com/rackt/react-redux                              
react-router-redux          dt      https://github.com/rackt/react-router-redux                       
redux                       dt      https://github.com/rackt/redux                                    
redux                       ambient                                                                   
redux-actions               dt      https://github.com/acdlite/redux-actions                          
redux-action-utils          dt      https://github.com/insin/redux-action-utils                       
redux-devtools              dt      https://github.com/gaearon/redux-devtools                  

```

## Typingsが正規で利用できるモジュール
Typingsが正規の(`--ambient`オプションなしで)利用できるのは、以下の場合のようです。

* `typings.json`が含まれたnpm、bower、githubなどのプロジェクト
	* 後ほど簡単に紹介しますが、Typingsではnpm、bowerから型定義をインストールできます。
* 公式リポジトリである、 https://github.com/typings/registry に登録された型定義

現在の所 https://github.com/typings/registry にあんまり数がなくて基本的にDefinitelyTypedなどからアンビエント宣言を取り込むことが多いので、`--ambient`オプションが必須みたいになっていますが、Typingsが普及してくれば`--ambient`オプションの出番も減るかもしれないですね。


# 便利な使い方

## npmから型定義ファイルをインストールする

npmから型定義を取得できます。といいつつ、実際にはプロジェクトの`node_modules`ディレクトリから型定義をコピーしてくるだけです。
つまり、前もって`npm install`で型定義を取得したいモジュールをインストールしておく必要があります。

```
typings install npm:<npmのモジュール名>/<モジュール内の.d.tsファイルへのパス> --name <適当な型定義名> --ambient
```

例えば、RxJSはnpmモジュールに型定義が同梱されているのでこの機能を利用して以下のように型定義をインストールできます。

```
cd typings-sample-project
npm install rx --save
typings install npm:rx/ts/rx.all.d.ts --save --name rx --ambient
```


また、前述のように、対象となるモジュールがTypingsを使用していて`typings.json`が含まれる場合、`--ambient`オプションを外して簡単にインストールできます。Typingsの公式ページでは[popsicle](https://www.npmjs.com/package/popsicle)[^2]の例が紹介されています。

[^2]: 作者がTypingsの中の人

```
typings install npm:popsicle --save
```

nodeの他、webpackやbrowserifyを利用している場合に便利かもしれません。

## bowerから型定義ファイルをインストールする

bowerから型定義を取得できます。といいつつ、実際にはプロジェクトの`bower_components`ディレクトリから(ry
前もって`bower install`で型定義を取得したいモジュールを取得しておく必要があります。

```
typings install bower:<bowerのモジュール名>/<モジュール内の.d.tsファイルへのパス> --name <適当な型定義名> --ambient
```

RxJSはbowerモジュールにも型定義が同梱されているのでこの機能を利用できます。

```
cd typings-sample-project
bower install rxjs --save
typings install bower:rxjs/ts/rx.all.d.ts --save --name rxjs --ambient
```

bowerを利用している場合に便利かもしれません。


## gulpと組み合わせてみる

以下のような感じでgulpタスクに組み込んで`typings install`を実行できます。

```coffeescript:typings.coffee
gulp = require('gulp')
typings = require('typings')

gulp.task 'typings', ->
  typingsInstallOption = {
    ambient: true
    cwd: process.cwd()
    save: false
  }
  typings.install(typingsInstallOption)
```

別にnpm-scriptsで`typings install && gulp build`とやってもいいんですけどね。

# とりあえず
いろいろできるんですが、tsdからの移行から始めるのがいいんじゃないでしょうか。