ライブラリ定義の作成
独自のlibdefを作成する時間を費やす前に、対象のサードパーティコードのlibdefが既に存在するかどうかを確認することをお勧めします。flow-typed
は、Flow コミュニティ内で共通のlibdefを共有するためのツールとリポジトリです。そのため、プロジェクトに必要な公開libdefの大部分を簡単に作成できます。
しかし、既存のlibdefがない場合や、公開されていないサードパーティコードがある場合、あるいは単に自分でlibdefを作成する必要がある場合もあります。これを行うには、作成する各libdefごとに.js
ファイルを作成し、プロジェクトルートの/flow-typed
ディレクトリに配置します。これらのlibdefファイルでは、特別なFlow構文(下記で説明)を使用して、関連するサードパーティコードのインターフェースを記述します。
グローバル関数の宣言
プロジェクト全体でアクセス可能なグローバル関数を宣言するには、libdefファイルでdeclare function
構文を使用します。
flow-typed/myLibDef.js
1declare function foo(a: number): string;
これにより、プロジェクト内の任意のコードがグローバル関数foo
を参照できるようになり、その関数は1つの引数(number
)を取り、string
を返します。
グローバルクラスの宣言
プロジェクト全体でアクセス可能なグローバルクラスを宣言するには、libdefファイルでdeclare class
構文を使用します。
flow-typed/myLibDef.js
1declare class URL {2 constructor(urlStr: string): URL;3 toString(): string;4
5 static compare(url1: URL, url2: URL): boolean;6}
これにより、プロジェクト内の任意のコードがグローバルクラスURL
を参照できるようになります。このクラス定義には実装の詳細が含まれていません。クラスのインターフェースのみを定義します。
グローバル変数の宣言
プロジェクト全体でアクセス可能なグローバル変数を宣言するには、libdefファイルでdeclare var
、declare let
、またはdeclare const
構文を使用します。
flow-typed/myLibDef.js
1declare const PI: number;
これにより、プロジェクト内の任意のコードがグローバル変数PI
(この場合はnumber
)を参照できるようになります。
グローバル型の宣言
プロジェクト全体でアクセス可能なグローバル型を宣言するには、libdefファイルでdeclare type
構文を使用します。
flow-typed/myLibDef.js
1declare type UserID = number;
これにより、プロジェクト内の任意のコードがグローバル型UserID
(この場合はnumber
のエイリアス)を参照できるようになります。
モジュールの宣言
多くの場合、サードパーティコードはグローバルではなくモジュール単位で整理されています。モジュールの存在を宣言するlibdefを作成するには、declare module
構文を使用します。
declare module "some-third-party-library" {
// This is where we'll list the module's exported interface(s)
}
declare module
の後に引用符で指定された名前は任意の文字列にできますが、プロジェクトにサードパーティモジュールをrequire
またはimport
するために使用する文字列と一致する必要があります。相対的なrequire
/import
パスを介してアクセスされるモジュールの定義については、.flow
ファイルに関するドキュメントを参照してください。
declare module
ブロックの本体内で、そのモジュールのエクスポートセットを指定できます。ただし、エクスポートについて説明する前に、Flowがサポートする2種類のモジュール、CommonJSとESモジュールについて説明する必要があります。
FlowはCommonJSモジュールとESモジュールの両方を処理できますが、declare module
を使用する際に考慮する必要があるいくつかの重要な違いがあります。
ESモジュールの宣言
ESモジュールには、**名前付き**エクスポートと**デフォルト**エクスポートの2種類のエクスポートがあります。Flowは、以下のようにdeclare module
本体内でこれらのいずれかまたは両方のエクスポートを宣言する機能をサポートしています。
名前付きエクスポート
flow-typed/some-es-module.js
declare module "some-es-module" {
// Declares a named "concatPath" export
declare export function concatPath(dirA: string, dirB: string): string;
}
declare module
の本体の中に他のものを宣言することもできますが、それらはdeclare module
の本体のスコープ内に限定されます。**ただし、モジュールからはエクスポートされません**
flow-typed/some-es-module.js
declare module "some-es-module" {
// Defines the type of a Path class within this `declare module` body, but
// does not export it. It can only be referenced by other things inside the
// body of this `declare module`
declare class Path {
toString(): string;
}
// Declares a named "concatPath" export which returns an instance of the
// `Path` class (defined above)
declare export function concatPath(dirA: string, dirB: string): Path;
}
デフォルトエクスポート
flow-typed/some-es-module.js
declare module "some-es-module" {
declare class URL {
constructor(urlStr: string): URL;
toString(): string;
static compare(url1: URL, url2: URL): boolean;
}
// Declares a default export whose type is `typeof URL`
declare export default typeof URL;
}
同じdeclare module
本体で**名前付き**エクスポートと**デフォルト**エクスポートの両方を宣言することもできます。
CommonJSモジュールの宣言
CommonJSモジュールには、エクスポートされる単一の値(module.exports
値)があります。declare module
本体内でこの単一値の型を記述するには、declare module.exports
構文を使用します。
flow-typed/some-commonjs-module.js
declare module "some-commonjs-module" {
// The export of this module is an object with a "concatPath" method
declare module.exports: {
concatPath(dirA: string, dirB: string): string;
};
}
declare module
の本体の中に他のものを宣言することもできますが、それらはdeclare module
の本体のスコープ内に限定されます。**ただし、モジュールからはエクスポートされません**
flow-typed/some-commonjs-module.js
declare module "some-commonjs-module" {
// Defines the type of a Path class within this `declare module` body, but
// does not export it. It can only be referenced by other things inside the
// body of this `declare module`
declare class Path {
toString(): string;
}
// The "concatPath" function now returns an instance of the `Path` class
// (defined above).
declare module.exports: {
concatPath(dirA: string, dirB: string): Path
};
}
注意:特定のモジュールはESモジュールとCommonJSモジュールの両方になることはできないため、同じdeclare module
本体でdeclare export [...]
とdeclare module.exports: ...
を混在させることはエラーになります。