TypeScript 类型推断

TypeScript 类型检查机制包含三个部分:

  • 类型推断
  • 类型保护
  • 类型兼容性

本节介绍其中的类型推断,类型推断主要用于那些没有明确指出类型的地方帮助确定和提供类型,这是 TypeScript 的一种能力。

类型推断是有方向的,要注意区分从左向右和从右向左两种推断的不同应用。

1. 慕课解释

类型推断的含义是不需要指定变量类型或函数的返回值类型,TypeScript 可以根据一些简单的规则推断其的类型。

2. 基础类型推断

基础的类型推断发生在 初始化变量,设置默认参数和决定返回值时。

初始化变量例子:

let x = 3             // let x: number
let y = 'hello world' // let y: string

let z                 // let z: any

代码解释:

变量 x 的类型被推断为数字,变量 y 的类型被推断为字符串。如果定义时没有赋值,将被推断为 any 类型。

设置默认参数和决定返回值时的例子:

// 返回值推断为 number
function add(a:number, b:10) {
  return a + b
}

const obj = {
  a: 10,
  b: 'hello world'
}

obj.b = 15 // Error,Type '15' is not assignable to type 'string'

代码解释:

第 1 行,参数 b 有默认值 10,被推断为 number 类型。

第 2 行,两个 number 类型相加,函数 add() 返回值被推断为 number 类型。

最后一行,obj 的类型被推断为 {a: number, b: string},所以属性 b 不能被赋值为数字。

const obj = {
  protagonist: 'Sherlock',
  gender: 'male'
}

let { protagonist } = obj

代码解释: 通过解构赋值也可以完成正确的类型推断:let protagonist: string

3. 最佳通用类型推断

当需要从多个元素类型推断出一个类型时,TypeScript 会尽可能推断出一个兼容所有类型的通用类型。

比如声明一个数组:

let x = [1, 'imooc', null]

代码解释: 为了推断 x 的类型,必须考虑所有的元素类型。这里有三种元素类型 number、string 和 null,此时数组被推断为 let x: (string | number | null)[] 联合类型。

Tip: 是否兼容 null 类型可以通过 tsconfig.json 文件中属性 strictNullChecks 的值设置为 true 或 false 来决定。

4. 上下文类型推断

前面两种都是根据从右向左流动进行类型推断,上下文类型推断则是从左向右的类型推断。

例如定义一个 Animal 的类作为接口使用:

class Animal {
  public species: string | undefined
  public weight: number | undefined
}

const simba: Animal = {
  species: 'lion',
  speak: true  // Error, 'speak' does not exist in type 'Animal'
}

代码解释: 第 6 行,将 Animal 类型显示的赋值给 变量 simbaAnimal 类型 没有 speak 属性,所以不可赋值。

5. 小结

本小节介绍了一些常见的类型推断方式,需要明白从右向左从左到右两种类型推断方法的区别及应用,在项目中灵活运用。