型推論

イントロダクション

このセクションでは、TypeScriptでの型推論について説明します。 具体的に言えば、何処でどのように型が推論されるのかについて説明します。

基本

TypeScriptでは、型が明示的に注釈(annotation)されていない場合に、 型推論が型を提供するタイミングが幾つか存在します。 例えば、このコードでは、

let x = 3;

x変数の型は、数値(number)であると推論されます。 この類の推論は、変数とメンバの初期化、パラメーターへのデフォルト値の設定、関数が返す型の判定のタイミングで行われます。

ほとんどのケースで、型推論は分かりやすいものになっています。 次のセクションでは、型がどのように推論されるのかを、幾つかの微妙な違いをもとに学習していきます。

「最も共通する型」(Best common type)

型推論が幾つかの式から作られる場合、それらの式の型は"「最も共通する型」"を算出されるのに使用されます。 例えば、

let x = [0, 1, null];

上記の例の型を推論するには、各配列要素の型を考慮しなければいけません。 ここでは、numbernullの2つの型を持つ配列が与えられています。 「最も共通する型」のアルゴリズムは、候補とする各型を考慮し、他の全ての候補と互換性のある型を選び出します。

「最も共通する型」は、提供される候補の型から選び出さなければいけないため、 どの型も共通の構造を共有しているものの、どれも全ての候補にあげられた型の親(super)の型では無いというケースが存在します。 例えば、

let zoo = [new Rhino(), new Elephant(), new Snake()];

理想を言えば、Animal[]として参照可能なzooがあればよいのですが、 配列内がAnimal型に制限されるようなオブジェクトが無いため、 そのような要素の型の配列を推論するわけにはいきません。 これを正すために、全ての他の候補の親(super)になる型が存在しない場合は、明確にその型を提供する必要があります。

let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];

「最も共通する型」が見つからない場合は、推論の結果は空のオブジェクト型{}になります。 この型はメンバーを持たないため、プロパティを使用しようとするとエラーが発生します。 この結果は、オブジェクトの型が暗黙的に確定されないケースで、型の安全(type safety)が提供されている間は、 型に影響を受けない方法であれば、オブジェクトの使用を可能なままにしてくれます。

文脈上(contextual)の型

TypeScriptでの型推論は、あるケースでは"逆方向(the other direction)"にも動作します。 これは、"文脈上の型付け(contextual typing)"として知られています。 文脈上の型付けは、式の型がその位置によって暗黙的に決定された際に発生します。 例えば、

window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.buton);  //<- Error
};

上記のコードにエラー型を与えるために、 TypeScriptの型チェッカーは右側の代入される関数式の型を推論するのに、 Window.onmousedown関数の型を使用します。 これを行ったことで、mouseEventパラメーターの型を推論できたわけです。

もし、この関数式に対して位置による文脈上の型付けができなかった場合、 mouseEventパラメーターはany型となり、エラーと判断されなかったでしょう。

もし、文脈上の型付けがされる式に明確な型情報が含まれている場合は、文脈上の型は無視されます。 上記の例を次のように書くことも可能です。

window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.buton);  //<- エラーになりません
};

パラメーターに明確なアノテーションのある関数式は、文脈上の型を上書きします。 これが行われると、文脈上の型が割り当てられることで発生するエラーが起こりません。

多くのケースで文脈上の型付けが適用されています。 一般的なケースには、引数を含む関数呼び出し、代入される式の右側部分、型注釈(type assertion)、 オブジェクトのメンバーと配列リテラル、戻り値の式があります。 文脈上の型は、「最も共通する型」の候補の型のようにも振る舞います。 例えば、

function createZoo(): Animal[] {
    return [new Rhino(), new Elephant(), new Snake()];
}

この例では、「最も共通する型」はAnimalRhinoElephantSnakeの4つが候補になります。 ここでは、「最も共通する型」のアルゴリズムからAnimalが選ばれます。

 Back to top

© https://github.com/Microsoft/TypeScript-Handbook

このページは、ページトップのリンク先のTypeScript-Handbook内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • ドキュメントの情報が古い可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。