- 基础
- 最佳通用类型
- 上下文类型
1. 基础
在 TS 中未明确指出类型的地方,TS 会帮助提供类型,当初始化变量和成员,设置默认参数值和决定函数返回值会发生这种自动推断,如变量 x
的类型被推断为 number
:
let x = 3;
2. 最佳通用类型
类型推断会尽量考虑到所有可能的候选类型,并给出兼容所有候选类型的类型。下例中存在两种可能:number
和 null
:
let y = [0, 1, null];
因为在第一篇介绍基础类型时就提到过:用 null
赋值给其他类型,默编译通过不报错:
let num: number = 3
num = null
所以 y
的类型被推断为 number[]
。
再看一个例子,由于通用类型取自提供的候选类型,而候选类型共享了通用类型,这里我们希望能自动推断为 Animal
类型,但是大多数类型推断都是直截了当的,而数组里没有对象是 Animal
类型,所以找不到最佳通用类型,变量 food
会被推断为联合类型 (Dog | Cat | Fish)[]
:
class Animal { }
class Dog extends Animal { }
class Cat extends Animal { }
class Fish extends Animal { }
let food = [new Dog(), new Cat(), new Fish()];
拯救的方法也很简单,手动明确地指出类型即可:
let food: Animal[] = [new Dog(), new Cat(), new Fish()];
3. 上下文类型
TS 的类型推断也可能会反向进行,这叫“按上下文归类”,如下所示
window.onmousedown = function(mouseEvent) {
console.log(mouseEvent.button); // 报错
};
这个函数表达式有明确的参数类型注解时,上下文类型会被忽略(屏蔽):
window.onmousedown = function(mouseEvent: any) {
console.log(mouseEvent.button); // 不报错
};
上下文(context)其实就是根据语境来推断,所以很多情况都会用到,比如函数的参数,赋值表达式的右边,类型断言,对象成员和数组字面量和返回值语句。我认为也不需要强记,像是 vscode 这种编辑器会给出必要提示的。
上下文类型也会做为最佳通用类型的候选类型之一,如下所示,显然 Animal[]
会做为最佳通用类型:
function createFood(): Animal[] {
return [new Dog(), new Cat(), new Fish()];
}