Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@jkr_2255

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

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がいるということになってしまって、その不都合は残ったままとなっています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
1
Help us understand the problem. What are the problem?