【Typescript】- Typescript高级

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

前言

我们在学习 Typescript 高级知识之前,先提前温习下前面的知识: Typescript预备知识Typescript基础知识Typescript进阶

高级知识

类型操作

我们前面在 Typescript 进阶知识学习了,简单的类型操作——keyof,那么下面我们继续学习 3 种相对复杂的类型操作。

映射类型

在了解映射类型之前,我们不妨看一个例子。

我们有一个User接口,现在有一个需求是把User接口中的成员全部变成可选的,我们应该怎么做?难道要重新一个个:前面加上?,手都加酸啦,有没有更便捷的方法呢?

interface User {
  username: string
  id: number
  token: string
  avatar: string
  role: string
}
复制代码

这个时候映射类型就派上用场了,映射类型的语法是[K in Keys]:

  • K:类型变量,依次绑定到每个属性上,对应每个属性名的类型。
  • Keys:字符串字面量构成的联合类型,表示一组属性名(的类型)。

我们使用映射类型,来实现上述需求,具体代码如下:

interface User {
  username: string
  id: number
  token: string
  avatar: string
  role: string
}

type partial<T> = { [K in keyof T]?: T[K] };
type partialUser = partial<User>;
复制代码

映射类型,其实是一种创建对象类型的方法。

映射类型 VS 对象类型

我们可以用描述集合的方法来形象地理解对象类型和映射类型:

描述集合的方法 描述对象类型的方法 举例
列举法 对象类型 type Person = {name: string, age: number}
公式法 映射类型 type Mapped = { [K in UnionType]: ValueType

映射类型、keyof、typeof、可选修饰符、只读修饰符结合

import { Equal } from '@type-challenges/unils';

type User = {
    id: number;
    name: string;
    age: number;
};

// 所有字段变为可选
type OptionalUser = { [K in keyof User]?: User[K] }
// 所有字段变为 nullable 的
type NullableUser = { [K in keyof User]: User[K] | null }
// 所有字段变为只读的
type ReadonlyUser = { readonly [K in keyof User]: User[K] }
// 所有字段去除只读
type User2 = { -readonly [K in keyof ReadonlyUser]: User[K] }
type R1 = Equal<User2, User>;// true
// 所有字段去除可选
type User3 = { [K in keyof OptionalUser]-?: User[K] }
type R2 = Equal<User3, User>;// true
复制代码

模板字面量类型

模板字面量类型,是在TS4.1引入的。通过它我们可以更方便地创建字符串字面量类型。

模板字面量 vs 模板字符串

模板字面量语法与模板字符串相同。我们下面来具体对比看看吧。 image.png

条件类型

条件类型,是在TS2.8时引入的。简单理解,条件类型就是通过判断两个类型之间的关系, 根据判断结果返回不同类型。其语法和三目运算符(X ? A : B)一样。

条件类型 vs 三目运算符

image.png

其他语言类似条件类型

其他语言中也有类似条件类型的特性。比如C++中可以通过模板特化实现。

#include <iostream>
template<typename T> // primary template
struct is_void : std::false_type{};
// 默认对任意T都继承自false_type

template<> // explicit specialization for T = void
struct is_void<void> : std::true_type{};
// 但当T=void时继承true_type

int main()
{
    std::cout << is_void<char>::value << '\n';// false_type::value = 0
    std::cout << is_void<void>::value << '\n';// true_type::value = 1
}
复制代码

条件类型高级话题

条件类型还有很多相关的知识话题,有兴趣可自行研究学习:

  1. 条件类型中的分配(Distributive Conditional Types) 2. infer关键字
  2. UnionToIntersection<U>
  3. 型变Variance

常用工具类

image.png 上图是 Typescript 常用的工具类型,详情可见lib.es5.d.ts

总结

学习完Typescript知识,我们可以认为TS的类型系统本身是一个用来“操作、创建”类型的“语言”。

  • 列举 ↔ 顺序执行
  • 映射类型 ↔ 循环
  • 条件类型 ↔ 条件判断

image.png

划重点:我们通过TS类型系统提供的这个 “语言”,精确的描述我们需要的类型。TS回报给我们的就是编译期就将问题提前暴露出来。代码更健壮、更易扩展。

Typescript 资源

书名 图片 特点
《TypeScript编程》 image.png 全面
《深入理解TypeScript》 image.png 深入
《高效TypeScript》 image.png 指导性、原则性
《TypeScript类型编程》 image.png 着重TS类型系统

猜你喜欢

转载自juejin.im/post/7036013407614533668