LoginSignup
3
2

More than 5 years have passed since last update.

TypeScript Handbook を読む (8. Type Inference)

Last updated at Posted at 2017-03-18

TypeScript Handbook を読み進めていく第八回目。

  1. Basic Types
  2. Variable Declarations
  3. Interfaces
  4. Classes
  5. Functions
  6. Generics
  7. Enums
  8. Type Inference (今ココ)
  9. Type Compatibility
  10. Advanced Types
  11. Symbols
  12. Iterators and Generators
  13. Modules
  14. Namespaces
  15. Namespaces and Modules
  16. Module Resolution
  17. Declaration Merging
  18. JSX
  19. Decorators
  20. Mixins
  21. Triple-Slash Directives
  22. Type Checking JavaScript Files

Type Inference

原文

Basics

TypeScript では、型が明示されていない場合に型推論が行われるところが何箇所かあります。
以下の例では x の型は number と推論されます。

TypeScript
let x = 3;

このタイプの推論は、変数やメンバの初期化時、デフォルト引数の設定時、関数の戻り値の型の決定時に行われます。

Best common type

複数の式に対して型推論が行われる場合、それらの式の "最適な共通型" が型として採用されます。

以下の例では、配列の各要素の型を基に x の型が推論されますが、各要素の型として number または null が考えられます。

TypeScript
let x = [0, 1, null];

--strictNullChecks を指定していない場合、nullnumber に代入できるので x の型は number[] になる。
--strictNullChecks を指定している場合、nullnumber に代入できないため、x の型は (number|null)[] になる。

最適な共通型は指定された型を基に選択されるため、以下の例では zoo の型が Animal[] として推論されてほしいと思うかもしれませんが、実際には各要素が Animal を継承したクラスではないのでそのようには推論されません。

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

これを修正するためには型を明示することです。

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

まあ意図しない推論を予防するためにも、なるべく型は指定した方が良いだろうね

そして、最適な共通型が見つからなかった場合には共用配列型 ((Rhino | Elephant | Snake)[]) が採用されます。

any とかになるわけではないのね

Contextual Type

TypeScript は他にも "文脈に基づく型付け" と呼ばれる推論も行いますが、これは型推論が行われる場所に基づいて行われます。

以下の例はエラーになりますが、これは右辺が Window.onmousedown に代入可能な関数であることに基づいて、mouseEvent 引数の型が自動的に推論されるためです。

TypeScript
window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.buton);  //<- エラー。正しくは 'button'
};

ただし、明示的に型が指定されている場合には、文脈に基づく型付けは行われません。

TypeScript
window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.buton);  //<- エラーにならなくなる
};

文脈に基づく型付けは、最適な共通型の候補にもなります。
以下の例では最適な共通型として、AnimalRhinoElephantSnake の中から Animal が選択されます。

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

戻り値の型を明示してるけど、例として正しいんだろうか?

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2