返回

typescript类型锚定在场景中的巧用(2)——概念回炉

前端

在上次分享了 typescript 类型锚定的方法后,和同事们又进行了一些点对点的讨论。在交流的过程中,我发现部分同学已经能较为熟练地使用 ts 的类型推导,但对某些不常见的 typescript 语法或类型定义方式却并不理解,甚至有时会出现一些低级的类型错误。经过多方面的考虑,我决定再写一篇博文,帮助大家理解这些复杂的 typescript 用法,并在一些场景中巧妙地利用这些 typescript 技巧。

TypeScript 类型锚定的重要性

在开始介绍这些复杂的 typescript 语法和类型定义方式之前,我们先来回顾一下 TypeScript 类型锚定的重要性。

类型锚定,简单来说就是告诉 typescript 编译器,某个变量或表达式的类型是什么。这可以帮助编译器更好地理解你的代码,并防止你出现一些不必要的错误。

例如,以下代码中的变量 name 没有指定类型,而变量 age 则指定了类型为 number

let name; // 变量 name 没有指定类型
let age: number; // 变量 age 指定了类型为 number

如果不指定类型,编译器就无法知道变量 name 的类型是什么,这可能会导致一些问题。例如,你可能会不小心将一个字符串值赋给 name 变量,但编译器却不会报错。

name = 'John'; // 编译器不会报错,但这是一个错误

if (name === 'John') {
  // ...
} else {
  // ...
}

在这个例子中,由于编译器不知道 name 变量的类型,所以它无法检查 name === 'John' 这个条件是否成立。这可能会导致一些意想不到的结果。

为了防止这种情况发生,我们应该显式地指定变量的类型。这可以帮助编译器更好地理解你的代码,并防止你出现一些不必要的错误。

TypeScript 类型锚定的方法

TypeScript 提供了几种方法来指定变量或表达式的类型。最常见的方法是使用类型注解。

let name: string; // 使用类型注解指定变量 name 的类型为 string

你也可以使用类型推导来指定变量或表达式的类型。类型推导是一种由编译器自动推断类型的方式。例如,以下代码中的变量 name 的类型是 string,而变量 age 的类型是 number

let name = 'John'; // 编译器自动推断变量 name 的类型为 string
let age = 30; // 编译器自动推断变量 age 的类型为 number

编译器可以通过查看变量的赋值语句来推断出变量的类型。例如,在上面的代码中,编译器看到变量 name 被赋值为一个字符串,所以它推断出 name 变量的类型为 string

TypeScript 类型锚定的技巧

除了使用类型注解和类型推导来指定变量或表达式的类型外,TypeScript 还提供了一些技巧来帮助你更好地利用 TypeScript 的类型系统。

类型别名

类型别名是一种可以让你为一种类型起一个别名的特性。这可以帮助你使你的代码更易于阅读和理解。

例如,以下代码中的 Person 类型别名定义了一个具有 nameage 属性的对象:

type Person = {
  name: string;
  age: number;
};

现在,你就可以使用 Person 类型别名来定义变量或表达式的类型了。例如,以下代码中的变量 person 的类型是 Person

let person: Person = {
  name: 'John',
  age: 30
};

接口

接口是一种可以让你定义一组相关属性的特性。这可以帮助你创建更具可读性和可维护性的代码。

例如,以下代码中的 IPerson 接口定义了一个具有 nameage 属性的对象:

interface IPerson {
  name: string;
  age: number;
}

现在,你就可以使用 IPerson 接口来定义变量或表达式的类型了。例如,以下代码中的变量 person 的类型是 IPerson

let person: IPerson = {
  name: 'John',
  age: 30
};

非空断言

非空断言运算符 (!) 可以让你告诉编译器,某个变量或表达式的值永远不会是 nullundefined。这可以帮助你避免一些不必要的类型错误。

例如,以下代码中的 name 变量被声明为一个 string 类型,但它被赋予了一个 null 值:

let name: string = null; // 这是一个类型错误

为了解决这个问题,你可以使用非空断言运算符来告诉编译器,name 变量永远不会是 null

let name: string = null!; // 使用非空断言运算符告诉编译器,name 变量永远不会是 null

现在,编译器就不会报错