宣言ファイル
宣言ファイルとは?
モジュールの型を宣言する、より一般的で、場合によってはより便利な方法である .flow
ファイルを見てみましょう。
実装ファイルが存在するかどうかに応じて、2つの使用ケースが考えられます。
最初のケースでは、モジュールのエクスポートされた型は、対応する *実装ファイル* <FILENAME>
と同じディレクトリにある *宣言ファイル* <FILENAME>.flow
で宣言されます。宣言ファイルは、同じ場所にある実装ファイルを完全にシャドウイングします。つまり、Flowは <FILENAME>
を完全に無視し、代わりに <FILENAME>.flow
のみを読み取ります。
2番目のケースでは、実装ファイルが完全に欠落しています。 <FILENAME>.flow
は、<FILENAME>
という名前であるかのように扱われます。
.flow
拡張子は、.js
ファイルと .json
ファイルの両方に適用されることに注意してください。対応する宣言ファイルの拡張子は、それぞれ .js.flow
と .json.flow
です。
それでは、上記で説明した最初のケースの例を見てみましょう。ファイル src/LookBeforeYouLeap.js
に次のコードがあるとします。
import { isLeapYear } from "./Misc";
if (isLeapYear("2020")) console.log("Yay!");
そして、src/Misc.js
に isLeapYear
の互換性のない実装があるとします。
1export function isLeapYear(year: number): boolean {2 return year % 4 == 0; // yeah, this is approximate3}
ここで宣言ファイル src/Misc.js.flow
を作成すると、src/Misc.js
のコードの代わりに、その中の宣言が使用されます。 src/Misc.js.flow
に次の宣言があるとします。
注:宣言ファイル内の宣言の構文は、ライブラリ定義の作成セクションで説明したものと同じです。
1declare export function isLeapYear(year: string): boolean;
どうなると思いますか?
そうです、宣言ファイルでは year
パラメータが string
を想定しているため、src/LookBeforeYouLeap.js
の isLeapYear
呼び出しは型チェックに合格します。
この例が示すように、宣言ファイルは注意深く記述する必要があります。宣言ファイルが正しいことを確認するのはプログラマーの責任であり、そうでない場合は型エラーが隠される可能性があります。
通常のコードに宣言をインライン化
実装ファイルのソースの一部として、宣言をインラインにすることが便利な場合があります。
次の例では、依存関係を最初にモックアップすることなく、関数 fooList
の記述を完了したいとします。依存関係は、number
を受け取って string
を返す関数 foo
と、map
メソッドを持つクラス List
です。これは、List
と foo
の宣言を含めることで実現できます。
1declare class List<T> {2 map<U>(f: (x: T) => U): List<U>;3}4declare function foo(n: number): string;5
6function fooList(ns: List<number>): List<string> {7 return ns.map(foo);8}
宣言を適切な実装に置き換えることを忘れないでください。