贝博恩创新科技网

TypeScript 2.0 教程,核心升级点有哪些?

TypeScript 2.0 是一个相当古老的版本(发布于 2025 年),自那时起,TypeScript 经历了多次重大更新(2.1, 2.4, 2.8, 3.0, 4.0, 5.0...),引入了大量新特性,如 unknown 类型、const 断言、可选链、空值合并、模板字面量类型等。

TypeScript 2.0 教程,核心升级点有哪些?-图1
(图片来源网络,侵删)

这份教程将分为两部分:

  1. 第一部分:TypeScript 2.0 核心概念,这部分内容是后续所有版本的基础,即使您现在学习最新版,这些知识也完全适用,我会重点介绍 2.0 版本引入和巩固的关键特性。
  2. 第二部分:从 2.0 到现代 TypeScript 的关键演进,这部分会简要介绍 2.0 之后出现的一些里程碑式特性,帮助您理解为什么现代 TypeScript 如此强大。

第一部分:TypeScript 2.0 核心概念

TypeScript 2.0 的主要目标是增强类型系统的安全性和易用性,它引入了两个非常核心的特性:strictNullChecks--strict 模式,以及更强大的 non-null assertion 操作符

环境搭建

在开始之前,请确保您的环境已准备好。

  1. 安装 Node.js: 从 nodejs.org 下载并安装 LTS 版本。
  2. 安装 TypeScript: 打开终端,运行以下命令全局安装 TypeScript。
    npm install -g typescript
  3. 验证安装: 检查版本。
    tsc --version

    您应该会看到类似 Version 5.0.0 或更高的版本,这没关系,因为 tsc 编译器向后兼容旧的语法。

    TypeScript 2.0 教程,核心升级点有哪些?-图2
    (图片来源网络,侵删)

strictNullChecks (严格空检查)

这是 TypeScript 2.0 最重要的特性之一,在 2.0 之前,nullundefined 可以被赋值给任何类型的变量,这常常导致运行时错误(著名的“Cannot read property 'x' of null”错误)。

开启 strictNullChecks: 在 tsconfig.json 文件中设置:

{
  "compilerOptions": {
    "strictNullChecks": true
  }
}

或者在命令行编译时加上 --strictNullChecks 标志。

示例:

TypeScript 2.0 教程,核心升级点有哪些?-图3
(图片来源网络,侵删)

不开启 strictNullChecks (旧版行为)

// 在 tsconfig.json 中设置 "strictNullChecks": false (这是默认值)
let name: string = "Alice";
name = null; // 编译器不会报错!
console.log(name.toUpperCase()); // 运行时错误: Cannot read property 'toUpperCase' of null

开启 strictNullChecks (2.0+ 行为)

// 在 tsconfig.json 中设置 "strictNullChecks": true
let name: string = "Alice";
name = null; // 编译时报错: Type 'null' is not assignable to type 'string'.
// 正确的做法是使用联合类型
let maybeName: string | null = "Bob";
maybeName = null; // OK
// 在使用前,必须检查是否为 null
if (maybeName) {
  console.log(maybeName.toUpperCase()); // OK, 在这个分支里 TypeScript 知道 maybeName 不是 null
} else {
  console.log("Name is null");
}

小结strictNullChecks 强迫你显式处理 nullundefined,从而在编译阶段就消灭了大量潜在的空指针异常。

--strict 模式

--strict 是一个“总开关”,它会同时开启一系列最严格的编译选项,包括 strictNullChecks,对于新项目,强烈建议始终开启这个模式。

{
  "compilerOptions": {
    "strict": true
  }
}

non-null assertion 操作符 ()

当你作为开发者,比编译器更确定一个值不会为 nullundefined 时,可以使用这个操作符来告诉编译器“相信我,这里没问题”。

它的语法是在变量或属性名后面加上一个感叹号 。

示例:

// 假设我们有一个从 DOM 获取元素的函数
const myElement = document.getElementById("my-button");
// myElement 的类型是 HTMLElement | null,因为元素可能不存在
// 错误用法:直接调用会报错,因为 myElement 可能为 null
// myElement.addEventListener('click', () => {}); // Error: Object is possibly 'null'.
// 解决方案 1: 使用类型守卫 (推荐)
if (myElement) {
  myElement.addEventListener('click', () => {});
}
// 解决方案 2: 使用 non-null assertion (当你 100% 确保它存在时)
const myElement2 = document.getElementById("my-button")!; // 告诉 TS 它不可能是 null
myElement2.addEventListener('click', () => {}); // OK

警告:滥用 操作符会绕过 TypeScript 的类型检查,可能导致运行时错误,请只在您有绝对把握时使用它。

基础类型回顾

这是 TypeScript 的基石,在 2.0 中已经非常完善。

  • number: 用于所有数字,无论是整数还是浮点数。

  • string: 用于文本数据。

  • boolean: 用于 truefalse

  • array: 两种定义方式:

    // 方式一: 在元素类型后面加上 []
    let list: number[] = [1, 2, 3];
    // 方式二: 使用泛型 Array<元素类型>
    let list2: Array<number> = [1, 2, 3];
  • tuple: 已知元素数量和类型的数组。

    // 定义一个包含 string 和 number 的元组
    let x: [string, number];
    x = ["hello", 10]; // OK
    // x = [10, "hello"]; // Error: Type 'number' is not assignable to type 'string'.
  • enum: 为一组数值赋予友好的名字。

    enum Color {Red, Green, Blue}
    let c: Color = Color.Green;
  • any: 允许任何类型,在不得已的情况下使用(处理来自第三方库的动态数据)。

  • void: 表示没有任何类型,通常用作函数没有返回值时的返回类型。

  • nullundefined: 在 strictNullChecks 下,它们只能赋值给 any 和它们各自的类型(null 只能赋给 nullundefined 只能赋给 undefined)。

接口

接口是 TypeScript 的核心概念之一,用于定义对象的形状。

// 定义一个接口
interface User {
  readonly id: number; // 只读属性
  name: string;
  age?: number; // 可选属性
}
// 实现接口
const user: User = {
  id: 1,
  name: "John Doe"
  // age 是可选的,所以可以不提供
};
// user.id = 2; // Error: Cannot assign to 'id' because it is a read-only property.

函数

// 为函数的参数和返回值添加类型注解
function add(x: number, y: number): number {
  return x + y;
}
// 箭头函数
const multiply = (x: number, y: number): number => {
  return x * y;
};
// 函数类型定义
let myFunc: (x: number, y: number) => number;
myFunc = add; // OK
// myFunc = (a: string, b: string) => a + b; // Error

TypeScript 2.0 的类支持了 ES6 的大部分特性,并增加了类型系统。

interface Animal {
  name: string;
  makeSound(): void;
}
class Dog implements Animal { // implements 关键字表示类遵循一个接口
  name: string;
  // 构造函数
  constructor(name: string) {
    this.name = name;
  }
  // 方法
  makeSound(): void {
    console.log(`${this.name} says: Woof!`);
  }
}
const myDog = new Dog("Rex");
myDog.makeSound(); // 输出: Rex says: Woof!

第二部分:从 2.0 到现代 TypeScript 的关键演进

了解 2.0 的基础后,了解一下后续版本的新特性会让你对 TypeScript 有更全面的认识。

特性 版本 简介
unknown 类型 0 unknownany 的类型安全版本,任何值都可以是 unknown,但必须先进行类型检查或类型断言才能使用它,有效防止了 any 带来的不安全性。
never 类型 0 0 正式完善了 never 类型,表示永不存在的值的类型,常用于函数抛出异常或无限循环,用于穷举类型检查。
类型推断增强 1+ 推断能力越来越强,很多情况下可以省略显式类型注解,让代码更简洁。
object 类型 2 引入了新的 object 类型,用来表示非原始类型(即不是 string, number, symbol, boolean, bigint, null, undefined 的类型)。
readonly 修饰符 & readonly 数组 4 允许将属性或数组元素设置为只读,提供了比 interface 中的 readonly 更细粒度的控制。
keyof 操作符 1 获取某个类型所有键名的联合类型。keyof { a: number, b: string }"a" \| "b"
typeof 操作符 1 在类型上下文中获取一个变量或表达式的类型。typeof myVar 会得到 myVar 的类型。
PickRecord 等实用工具类型 1 提供了一系列预定义的工具类型,用于从现有类型创建新类型,非常强大。
可选链 () 7 简化深层嵌套对象属性的访问,如果中间某个属性为 nullundefined,表达式会短路并返回 undefined,而不会报错。
空值合并 () 7 提供了一个比 更安全的空值检查。 只在左侧为 nullundefined 时返回右侧的值,而 在为“假值”(0, , false 等)时也会返回右侧的值。
const 断言 (as const) 4 将一个值或对象的所有属性标记为 readonly,并将字面量类型推断为最窄的类型。
模板字面量类型 1 允许你通过模板字符串字面量来创建字符串类型,可以结合 keyof 和泛型实现强大的类型约束。
satisfies 操作符 9 一个非常新的操作符,它确保一个表达式满足某个类型,但不改变该表达式的原始推断类型。

总结与学习建议

  1. 打好基础是关键:TypeScript 2.0 引入的 严格模式空检查 是现代 TypeScript 开发的基石,请务必深刻理解它们的工作原理。
  2. 从 2.0 开始,逐步进阶:您可以将这份教程作为起点,掌握了这些核心概念后,再逐步学习后续版本的新特性,官方的 TypeScript 手册 是最好的学习资源,它会按版本记录所有新特性。
  3. 实践出真知:不要只看不练,尝试用 TypeScript 重写一些你现有的 JavaScript 项目,或者创建一些小工具,在实践中遇到问题,然后去查资料解决,这是最高效的学习方式。
  4. 拥抱现代特性:一旦掌握了基础,请尽快学习和使用 可选链 ()空值合并 ()unknown 等现代特性,它们能极大地提升你的开发效率和代码质量。
分享:
扫描分享到社交APP
上一篇
下一篇