程序员scholar 程序员scholar
首页
  • Web 三剑客

    • HTML
    • CSS
    • JavaScript
  • 现代 JavaScript

    • ES6
    • TypeScript
  • 前端工具库

    • jQuery
    • Ajax
    • Axios
  • Vue 生态

    • Vue2
    • Vue3
    • Vue3 + TS
    • Vuex
  • 小程序开发

    • 微信小程序
    • uni-app
  • 构建工具

    • Webpack
  • 服务端技术

    • Node.js
  • 实时通信

    • WebSocket
    • 第三方登录
  • Element-UI
  • Apache ECharts
后端 (opens new window)
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Web 三剑客

    • HTML
    • CSS
    • JavaScript
  • 现代 JavaScript

    • ES6
    • TypeScript
  • 前端工具库

    • jQuery
    • Ajax
    • Axios
  • Vue 生态

    • Vue2
    • Vue3
    • Vue3 + TS
    • Vuex
  • 小程序开发

    • 微信小程序
    • uni-app
  • 构建工具

    • Webpack
  • 服务端技术

    • Node.js
  • 实时通信

    • WebSocket
    • 第三方登录
  • Element-UI
  • Apache ECharts
后端 (opens new window)
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • TypeScript

    • TypeScript - 介绍
    • TypeScript - 安装和使用
    • TypeScript - 基本类型
    • TypeScript - 编译和配置
    • TypeScript - 文件打包
    • TypeScript - 接口
    • TypeScript - 函数
    • TypeScript - 类
    • TypeScript - 泛型
    • TypeScript 的导入导出
    • TypeScript - 类型推断
      • 1. 基础
      • 2. 最佳通用类型
      • 3. 上下文类型
    • TypeScript - 高级类型
  • JS 超集语言 - TypeScript
  • TypeScript
scholar
2023-09-08
目录

TypeScript - 类型推断

  • 1. 基础
  • 2. 最佳通用类型
  • 3. 上下文类型

# 1. 基础

在 TypeScript 中,当变量、参数或者返回值没有明确指定类型时,TypeScript 会尝试根据代码中的上下文推断出一个类型,这被称为 类型推断。类型推断帮助开发者简化代码,并且提高代码的可读性和安全性。

示例:

let x = 3;
1

在上面的示例中,变量 x 被初始化为数字 3,因此 TypeScript 推断 x 的类型为 number。这种推断不仅适用于变量的初始化,还包括对象属性的初始化、函数参数的默认值和函数返回值的推断等场景。

大多数情况下,类型推断是直观且正确的,但在某些复杂场景下可能需要更仔细地分析和理解。

# 2. 最佳通用类型

有时候,我们需要从多个表达式中推断出一个最合适的通用类型。TypeScript 会基于这些表达式的类型推断出一个可以兼容所有候选类型的类型,这被称为 最佳通用类型。

示例:

let x = [0, 1, null];
1

在上面的示例中,数组 x 包含了数字和 null 值。为了推断 x 的类型,TypeScript 需要考虑所有数组元素的类型:number 和 null。因此,x 被推断为 Array<number | null> 类型,即 number 和 null 的联合类型。

当候选类型共享一个公共结构,但没有一个类型可以作为所有候选类型的超级类型时,TypeScript 可能无法找到一个最佳通用类型。在这种情况下,需要显式地指定类型。

示例:

class Animal {
    numLegs: number;
}

class Bee extends Animal {
}

class Lion extends Animal {
}

let zoo = [new Bee(), new Lion()];
1
2
3
4
5
6
7
8
9
10
11

在上面的示例中,我们希望 zoo 被推断为 Animal[] 类型,但因为数组中的元素是 Bee 和 Lion 类型,TypeScript 无法自动推断出 Animal[]。我们需要显式地声明预期的类型:

let zoo: Animal[] = [new Bee(), new Lion()];
1

如果不指定类型,zoo 将被推断为联合数组类型:(Bee | Lion)[]。通过明确地声明类型,我们可以确保 zoo 是 Animal[] 类型,从而确保代码的正确性和可维护性。

# 3. 上下文类型

在某些情况下,TypeScript 的类型推断会根据代码的上下文来决定类型,这种机制被称为 上下文类型。上下文类型与表达式的位置和预期类型有关。它可以帮助 TypeScript 在特定位置推断出变量或函数参数的类型。

示例:

window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.clickTime);  // Error
}
1
2
3

在这个示例中,TypeScript 会根据 window.onmousedown 的类型来推断右侧函数表达式的参数类型。window.onmousedown 预期接收一个 MouseEvent 类型的参数,因此 TypeScript 推断 mouseEvent 是 MouseEvent 类型。然而,由于 MouseEvent 类型没有 clickTime 属性,因此会产生类型错误。

如果明确为函数表达式的参数添加类型注解,则上下文类型会被忽略:

window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.clickTime);  // OK
}
1
2
3

在这个例子中,函数参数 mouseEvent 被显式声明为 any 类型,TypeScript 不再使用上下文类型进行推断,因此不会报错。

上下文类型在多种情况下都会被使用,包括函数参数、赋值表达式的右侧、类型断言、对象成员、数组字面量和返回语句等。它也会被用作确定最佳通用类型的候选类型之一。

示例:

function createZoo(): Animal[] {
    return [new Bee(), new Lion()];
}

let zoo = createZoo();
1
2
3
4
5

在这个例子中,返回语句 [new Bee(), new Lion()] 包含了 Animal、Bee 和 Lion 三个候选类型。TypeScript 使用上下文类型 Animal[] 来推断最佳通用类型,因此 createZoo 函数返回类型被推断为 Animal[]。

上下文类型使得 TypeScript 能够根据代码的位置和预期行为进行更加准确的类型推断,从而提高代码的安全性和可读性。

编辑此页 (opens new window)
TypeScript 的导入导出
TypeScript - 高级类型

← TypeScript 的导入导出 TypeScript - 高级类型→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式