程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

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

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
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)
上次更新: 2024/12/28, 18:32:08
TypeScript 的导入导出
TypeScript - 高级类型

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

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