本文へスキップ

ライブラリ定義の作成

独自の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 vardeclare 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: ...を混在させることはエラーになります。