オブジェクト型

特化シグネチャ

このエントリーをはてなブックマークに追加
最終更新日 2016-12-31

TypeScript のコールシグネチャ、メソッドシグネチャ、コンストラクトシグネチャはオーバーロードに対応しています。

// コールシグネチャのオーバーロードの例
var fooCall: {
    (x: string): string;
    (x: number): number;
};
fooCall("TypeScript");
fooCall(123);

// メソッドシグネチャのオーバーロードの例
var fooMethod: {
    bar(x: string): string;
    bar(x: number): number;
};
fooMethod.bar("TypeScript");
fooMethod.bar(123);

// コンストラクトシグネチャのオーバーロードの例
var fooConstruct: {
    new (x: string);
    new (x: number);
};
new fooConstruct("TypeScript");
new fooConstruct(123);

ところで、引数の型注釈として、String プリミティブ型のサブタイプである文字列リテラル型を指定することで、シグネチャを特化させることができます。 次に示すのは、コールシグネチャを特化させる例です。

interface FooBase {
    foo(): void;
}

interface Foo1 extends FooBase {
    foo1(): void;
}

interface Foo2 extends FooBase {
    foo2(): void;
}

var bar: {
    (x: "foo1"): Foo1;     // 特化シグネチャ 1
    (x: "foo2"): Foo2;     // 特化シグネチャ 2
    (x: string): FooBase;  // 通常のコールシグネチャ
};

var result1: Foo1 = bar("foo1");
var result2: Foo2 = bar("foo2");
var result3: FooBase = bar("TypeScript");

上記の例では、特化シグネチャ 1 の引数は文字列リテラル型 "foo1" であるため、 引数に文字列リテラル "foo1" を指定して bar() 呼び出すと、特化シグネチャ 1 が参照されます。 同様に、引数に文字列リテラル "foo2" を指定して bar() を呼び出すと、特化シグネチャ 2 が参照されます。 どちらにも合致しない文字列リテラルを指定して bar() を呼び出すと、通常のコールシグネチャが参照されます。

なお、特化シグネチャは、通常のシグネチャのサブタイプである必要があります。 上記の例では、2 種類の特化シグネチャの戻り値の型 Foo1 と Foo2 は、通常のコールシグネチャの戻り値の型 FooBase のサブタイプです。