.d.tsをどうつくるか

Angularが教えてくれた。

TypeScriptの学びの中で、他のライブラリの型情報をどう手に入れるかは説明されているのだけど、ライブラリとしてどのように型情報を提供するのかはあまり説明されていない。ECMAScriptで書かれたライブラリに後付けでindex.d.tsだけ書かれ、それが@typesに登録されているというのがよくあるケースだけども、そもそもTypeScriptで書いてる場合はどうしたらよいのか。まさか二度手間にチマチマ書きおろすわけもなかろうと調べてるうちに、事例としてとてつもなく巨大なのがあるのを思い出しました。Angularです。たぶんこいつはTypeScriptで書かれた世界最大のソフトウェアなんじゃないかなと思います。実際に、Angularはチマチマindex.d.tsを書くなんてことはしていなく、以下のようなindex.tsを用意しています。

// index.ts
export * from './public_api';

このexportしている元を辿って行っても、何段階かは同じようにexport * from XXXというのが徐々に増えながら続いたりもします。そしてこのソースコードを以下のコンパイラオプションで変換する。出力先は私はlibにしましたが、これはお好きなもので結構です。

// tsconfig.json
{
    "compilerOptions": {
        "outDir": "lib",
        "declaration": true,
    }
}

declarationスイッチをtrueにすると、全ての.tsファイルから.jsファイルと.d.tsファイルのペアを生成します。index.tsをコンパイルすると、index.jsとindex.d.tsを作ってくれる。そしてこのできたindex.d.tsをpackage.jsonで明らかにすればよい。

// package.json
{
    "main": "./lib/index.js",
    "types": "./lib/index.d.ts",
}

これでライブラリを利用するのがECMAScriptからでもTypeScriptからでも可能になります。