LoginSignup
3
1

More than 5 years have passed since last update.

1関数だけexportする場合の.d.tsファイルの書き方

Posted at

Visual Studio Codeを使ってJavaScriptだけ書くつもりだったのですが、TypeScriptの型情報があればIntelliSenseも便利に使えるということで、npmで使おうとしたモジュールに.d.tsファイルを用意してみることにしました。ただ、正しく動作させる方法がわからず、見様見真似で動くものにした、という感じです。

使ってみたnpmモジュール

また例によってパズルソルバーを作っていたのですが、その過程で「タテヨコにつながったマスの範囲」を調べる必要が出てきました。どこかに適当なライブラリはないかと探してみると、n-dimensional-flood-fillというのが見つかりました。

これは、requireすると、1つの関数が現れます。そして、そこにオプションを指定すると、返り値としてつながったものの座標の配列が来る、という流れになっています。

型宣言を作ってみる

まずは、引数と返り値の型宣言をしてみましたが、こちらはすんなり書けました。

引数の型宣言
interface NDimensionalFloodFillOptions<T>{
    /**
     * function getting a value from specified position.
     */
    getter: (...position: number[]) => T;
    /** 
     * initial position for flooding
     */
    seed: number[];
    /**
     * a callback called when one cell is flooded. (optional)
     */
    onFlood?: (...position: number[]) => any;
    /**
     * a callback called when one cell is marked as boundary. (optional)
     */
    onBoundary?: (...position: number[]) => any;
    /**
     * a callcack deciding whether two cells are equal.
     * default: comparison by ===
     */
    equals?: (arg1: T, arg2: T) => boolean;
    /** true if floodable to diagonal cells. (default: false) */
    diagonals?: boolean;
}

なお、getterで取ってくるものと、equalsで比較評価するものは同じ型のはずなので、<T>でジェネリクスとしています。また、on***の返り値は特に使わないので、チェック不要ということでanyとしています。

返り値の型宣言
interface NDimensionalFloodFillResult{
    flooded: number[][];
    boundaries: number[][];
}

n次元」という処理内容の都合上、一部の配列の要素数は同じと決まってくるのですが、それをTypeScript上で表現する方法は見つかりませんでした。

エクスポートするものの宣言…どうする?

そして、本題の関数について宣言してみるとこんな感じになります。

関数の宣言
declare function floodFill<T>(options: NDimensionalFloodFillOptions<T>) : NDimensionalFloodFillResult;

ところが、これをモジュールでエクスポートしようとするとさあ大変でした。コンパイルが通らないとか、モジュールから直接関数にならずに、.floodFillとして置かれてしまうなど、なかなかうまく行きませんでした。結局、関数である$をエクスポートしているjQueryの定義ファイルを参考に、関数でなくインターフェースとして用意してみることにしました。

とりあえずこんな形に
interface NDimensionalFloodFillFunction{
    <T>(options: NDimensionalFloodFillOptions<T>) : NDimensionalFloodFillResult;
}

declare var floodFill: NDimensionalFloodFillFunction;

declare module "n-dimensional-flood-fill"{
    export = floodFill;
}

とすることで、とりあえずVisual Studio Codeでは使えるようになりました。ただ、この宣言だとグローバルにfloodFillがいるということになってしまって、その不都合は残ったままとなっています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1