一、类型推断(type inference)

1.最佳通用类型

为了推断x的类型,我们必须考虑所有元素的类型。 这里有两种选择:numbernull。 计算通用类型算法会考虑所有的候选类型,并给出一个兼容所有候选类型的类型

  1. let zoo = [new Rhino(), new Elephant(), new Snake()];
  2. let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];
  3. //或者【联合类型】
  4. let zoo: (Rhino | Elephant | Snake)[] = [new Rhino(), new Elephant(), new Snake()];

2.上下文类型

TypeScript类型推论也可能按照相反的方向进行。
如果上下文类型表达式包含了明确的类型信息,上下文的类型被忽略

  1. window.onmousedown = function(mouseEvent: any) {
  2. console.log(mouseEvent.button); //<- Now, no error is given
  3. };

二、类型兼容性

TypeScript里的类型兼容性是基于结构子类型的。 结构类型是一种只使用其成员来描述类型的方式。

两个类型包含的子结构一样,即可通用

1. 关于可靠性的注意事项

TypeScript结构化类型系统的基本规则是,如果x要兼容y,那么y至少具有与x相同的属性
这个比较过程是递归进行的,检查每个成员及子成员

2. 比较两个函数

  1. let x = (a: number) => 0;
  2. let y = (b: number, s: string) => 0;
  3. y = x; // OK
  4. x = y; // Error

1. 函数参数双向协变

当源函数参数能够赋值给目标函数或者反过来时才能赋值成功

2.可选参数及剩余参数

比较函数兼容性的时候,可选参数与必须参数是可互换的。 源类型上有额外的可选参数不是错误,目标类型的可选参数在源类型里没有对应的参数也不是错误。

3.函数重载

源函数的每个重载都要在目标函数上找到对应的函数签名

3.枚举

枚举类型与数字类型兼容,并且数字类型与枚举类型兼容。不同枚举类型之间是不兼容的。

4.类

类与对象字面量和接口差不多,但有一点不同:类有静态部分和实例部分的类型。 比较两个类类型的对象时,只有实例的成员会被比较。 静态成员和构造函数不在比较的范围内

5.泛型

因为TypeScript是结构性的类型系统,类型参数只影响使用其做为类型一部分的结果类型