Type Inference
类型推断(Type Inference)
介绍
在本节中,我们将介绍TypeScript中的类型推断。也就是说,我们将讨论在何处以及如何推断类型。
基本
在 TypeScript 中,有几个地方使用类型推断来提供没有显式类型注释的类型信息。例如,在这个代码中
let x = 3;
该x
变量的类型被推断为number
。初始化变量和成员,设置参数默认值以及确定函数返回类型时会发生这种推断。
在大多数情况下,类型推断很简单。在下面的章节中,我们将探讨一些如何推断类型的细微差别。
最常见的类型
当从几个表达式中进行类型推断时,这些表达式的类型被用来计算“最佳公共类型”。例如,
let x = [0, 1, null];
为了推断上例中的类型x
,我们必须考虑每个数组元素的类型。在这里我们给出了数组类型的两个选择:number
和null
。最佳通用类型算法考虑每个候选类型,并选择与所有其他候选类型兼容的类型。
因为最好的通用类型必须从提供的候选类型中选择,所以有些情况下类型共享一个通用结构,但没有一种类型是所有候选类型的超类型。例如:
let zoo = [new Rhino(), new Elephant(), new Snake()];
理想情况下,我们可能想要zoo
推断为一个Animal[]
,但是因为没有严格Animal
的数组类型的对象,所以我们不会推断数组元素的类型。为了解决这个问题,在没有其他类型是所有其他候选人的超类型时,应明确提供类型:
let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];
如果找不到最佳通用类型,则得出的推论是联合数组类型,(Rhino | Elephant | Snake)[]
。
上下文类型
在TypeScript中的某些情况下,类型推断也适用于“其他方向”。这被称为“上下文键入”。当表达式的类型被其位置所暗示时,就会发生上下文类型化。例如:
window.onmousedown = function(mouseEvent) {
console.log(mouseEvent.button //<- Error
};
对于上面给出类型错误的代码,TypeScript 类型检查器使用Window.onmousedown
函数的类型来推断赋值右侧的函数表达式的类型。当它这样做时,它能够推断mouseEvent
参数的类型。如果此函数表达式不处于上下文类型的位置,则mouseEvent
参数将具有类型any
,并且不会发出错误。
如果上下文类型化表达式包含显式类型信息,则会忽略上下文类型。如果我们写了上面的例子:
window.onmousedown = function(mouseEvent: any) {
console.log(mouseEvent.button //<- Now, no error is given
};
带参数的显式类型注释的函数表达式将覆盖上下文类型。一旦这样做,不会给出错误,因为没有上下文类型适用。
上下文分类适用于许多情况。常见情况包括函数调用的参数,赋值的右侧,类型断言,对象和数组文字的成员以及返回语句。上下文类型还充当最佳通用类型的候选类型。例如:
function createZoo(): Animal[] {
return [new Rhino(), new Elephant(), new Snake()];
}
在这个例子中,最常见的类型有一组的四名候选人:Animal
,Rhino
,Elephant
,和Snake
。其中,Animal
可以通过最佳常见类型算法来选择。