typescript类型锚定在场景中的巧用(2)——概念回炉
2023-09-19 15:06:56
在上次分享了 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
类型别名定义了一个具有 name
和 age
属性的对象:
type Person = {
name: string;
age: number;
};
现在,你就可以使用 Person
类型别名来定义变量或表达式的类型了。例如,以下代码中的变量 person
的类型是 Person
:
let person: Person = {
name: 'John',
age: 30
};
接口
接口是一种可以让你定义一组相关属性的特性。这可以帮助你创建更具可读性和可维护性的代码。
例如,以下代码中的 IPerson
接口定义了一个具有 name
和 age
属性的对象:
interface IPerson {
name: string;
age: number;
}
现在,你就可以使用 IPerson
接口来定义变量或表达式的类型了。例如,以下代码中的变量 person
的类型是 IPerson
:
let person: IPerson = {
name: 'John',
age: 30
};
非空断言
非空断言运算符 (!
) 可以让你告诉编译器,某个变量或表达式的值永远不会是 null
或 undefined
。这可以帮助你避免一些不必要的类型错误。
例如,以下代码中的 name
变量被声明为一个 string
类型,但它被赋予了一个 null
值:
let name: string = null; // 这是一个类型错误
为了解决这个问题,你可以使用非空断言运算符来告诉编译器,name
变量永远不会是 null
:
let name: string = null!; // 使用非空断言运算符告诉编译器,name 变量永远不会是 null
现在,编译器就不会报错