typescript 类型推论


作者:Seiya

时间:2019年07月30日


前言


如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。




什么是类型推论


TypeScript 里,在有些没有明确指出类型的地方,类型推论会帮助提供类型。如下面的例子:

let myFavoriteNumber = 'seven';
myFavoriteNumber = 7;

以上代码虽然没有指定类型,但是会在编译的时候报错,事实上,它等价于:

let myFavoriteNumber: string = 'seven';
myFavoriteNumber = 7;

如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:

let myFavoriteNumber;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;



最佳通用类型


当需要从几个表达式中推断类型时候,会使用这些表达式的类型来推断出一个最合适的通用类型。例如:

let x = [0, 1, null];

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




上下文归类


TypeScript 类型推论也可能按照相反的方向进行。 这被叫做“上下文归类”。按上下文归类会发生在表达式的类型与所处的位置相关时。比如:

window.onmousedown = function(mouseEvent) {
	console.log(mouseEvent.button); //<- OK
	console.log(mouseEvent.kangaroo); //<- Error!
};

TypeScript 类型检查器会使用 Window.onmousedown 函数的类型来推断右边函数表达式的类型。 所以它能够推断出 mouseEvent 参数的类型中包含了 button 属性而不包含 kangaroo 属性。


TypeScript 还能够很好地推断出其它上下文中的类型:

window.onscroll = function(uiEvent) {
	console.log(uiEvent.button); //<- Error!
};

上面的函数被赋值给 window.onscroll,TypeScript 能够知道 uiEvent 是 UIEvent,而不是 MouseEventUIEvent 对象不包含 button 属性,因此 TypeScript 会报错。


我们也可以明确地为函数参数类型赋值来覆写上下文类型:

window.onscroll = function(uiEvent: any) {
	console.log(uiEvent.button); //<- Now, no error is given
};

但这段代码会打印 undefined,因为 uiEvent 并不包含 button 属性。

最后更新时间: 2019-7-31 11:44:42