ソースコードからドキュメントを生成するツールに JSDoc や ESDoc がありますが、 JavaScript ではなく TypeScript からドキュメントを作ることができれば、ソースコードの中に型定義を書くことができるので JSDoc とかつかうより楽に書けそうな気がします。

TypeScript からドキュメントを生成できる typedoc という npm モジュールがあったので使ってみました。

インストール

npm で普通に。

$ npm install -D typedoc

ドキュメントを生成

まずは 適当な TypeScript を用意して試してみます。

// a.ts

class A {
    constructor(public a: number) {}

    method() {
        return 0;
    }
}
typedoc --mode file --out doc a.ts

これで doc の中に HTML が生成されました。 doc/index.html を開くと A クラスのドキュメントができていることがわかります。

--mode file はファイルのドキュメントを生成します。

A#method の返り値はソースコードでは省略していますが、ドキュメントにはしっかり number と書かれていました。しかし、 return 0;return (a = 1) => \${a * 2}`;にすると(a?: number) => strengではなく(Anonymous function)` になってしまったので、複雑な型の推論は期待しないほうがいいかもしれません。

モジュールのドキュメント

上の例だとグローバルに A というクラスを作りました。次は export を使った外部モジュールの場合を試してみます。

export class A {
    constructor(public a: number) {}

    method() {
        return (a = 1) => `${a * 2}`;
    }
}
typedoc --mode modules --entryPoint '"a"' --module commonjs --out doc a.ts

--mode modules を指定するとモジュールごとのドキュメントができます。さらに --entryPoint '"a"' を指定すると "a" のドキュメントを doc/globals.html に直接出してくれます。 --module commonjs は内部で使っている TypeScript に渡されるオプションです。これがないとエラーが出ました。

ちなみにちょっと前まで内部モジュールと呼ばれていた namespace のモジュールも作れました。全体を namespace ns { ... } で囲って --entryPoint ns を指定すると doc/globals.htmlns のドキュメントになります。

JSDoc 風のコメント

JSDoc 風のコメントをつけてしっかりしたドキュメントを作ってみます。

/**
 * Aなかんじのクラス
 *
 * えー
 */
export class A {
    /**
     * Aなかんじのクラスのコンストラクタ
     *
     * えーえー
     *
     * @param a えー感じのパラメータ
     */
    constructor(
        /**
         * ぷろぱてぃ
         */
        public a: number
    ) {}

    /**
     * メソッド
     *
     * めそ
     *
     * @returns アレな関数
     */
    method() {
        return (a = 1) => `${a * 2}`;
    }
}

これでドキュメントを生成すると、きちんと説明が付加されていました。

さいごに

簡単にですが TypeScript からドキュメントを生成できる typedoc を試しました。 TypeScript で作ってあれば適当でもドキュメントが作れるのは、楽でいい感じです。すでに TypeScript でコードが書かれている場合は簡単に導入できると思います。

--includeDeclarations オプションを付けると .d.ts しかなくても生成してくれるみたいなので、 ソース自体は JavaScript で書いてあるけれど、 TypeScript用の .d.ts を書くついでにドキュメントも生成する、なんていう導入の仕方もできそうです。