Skip to content

第09章 深入infer、TS高级类型、泛型再进阶【全方位深度掌握 TS 泛型】

5-1 学习 infer+ TS 高级类型的价值和意义

TypeScript 提供了较多的高级类型,通过学习高级类型可以帮助提高 TS 代码的灵活运用能力, 掌握好这些高级类型能进一步提升我们对泛型的理解和驾驭能力, 让 TS 功底更深厚,把我们的TS水平推向一个更高的层次, 无论以后在项目中运用 TS 还是对理解源码的复杂 TS 泛型语法都有不小的帮助, 由于 TS 高级类型为我们提供了很多技巧性强的功能, 当我们在项目中遇到使用这些功能的应用场景时,会给项目带来更简洁,更轻量级的实现效果, 比如:如果我们项目中只需要查询 key value 数据,那么 Record 类型 就是轻量级的 Map , 再比如 Omit 快捷 爬取 Todo列表中的数据,保证编辑和预览时的不同效果。

5-2 【 infer 】 理解替换“神器” infer + infer和泛型的区别 【原理+使用案例】

infer 的定义:infer 表示在 extends 条件语句中以占位符出现的用来修饰数据类型的关键字,被修饰的数据类型等到使用时才能被推断出来。

infer 占位符式的关键字出现的位置:通常infer出现在以下三个位置上。

(1)infer 出现在 extends 条件语句后的函数类型的参数类型位置上

(2)infer 出现在 extends 条件语句后的函数类型的返回值类型上

(3) infer 会出现在类型的泛型具体化类型上。

  • 作用:infer 用来推断函数类型的参数类型和返回值类型,以及泛型具体化类型。

一个类有双重性质,既是构造函数对象变量,又是类型

typeof People // People-构造函数对象变量

new People() // People-类型

5-5 【TS 高级 type 类型】 详尽解说 Extract 不同场景下的不同理解+ 和类型断言的异同**

本节课程安排:

(1) 详解 Extract.ts

Extract<A, B> 读作 A中的每个元素是否都属于B,如果属于则返回A,否则返回never

(2) 从结果上详细对比的 Extract 泛型约束和类型断言【父子类】

子类可以断言为父类,父类也可以断言为子类

子类可以extends父类,父类不可以extends子类

(3) 从结果上详细对比 Extract 泛型约束和类型断言【联合类型】

(4) 从结果上详细对比 Extract 泛型约束和类型断言 【函数】

函数类型上的泛型约束 参数类型和返回值完全相同的情况下, 参数少的函数类型 extends 参数多的函数类型 返回true 参数多的函数类型 extends 参数少的函数类型 返回false

  • Extract 是TS提供的一个TS高级type类型【简称TS高级类型】
  • Extract 在 父类和子类中应用
    • 定律:子类 extends 父类=>子类 extends 父类永远返回true=>返回T类型
    • 定律: 父类 extends 子类=>父类 extends 子类返回false 因为父类继承子类本身不成立,所以一般都为false
    • 但如果希望人为制造一个true 那只有子类实例属性或实例方法个数必须和父类一样多
5-6【TS 高级 type 类型】 详尽解说 Exclude 【掌握 Omit 前 必会 】**

本节课程安排:

(1)type 类型在 Exclude 中的理解

(2)联合类型在 Exclude 的 分解理解

ts
type Exclude<T, U> = T extends U ? never : T

从T中排除U

  • 排除条件成立的类型,保留不符合泛型约束条件的类型
5-7 【TS 高级 type 类型】 完成异步数据扁平化(轻量级 Map)【真实应用场景】**
ts
type Record<T> = {
	[P in keyof any]: T
}

本讲课程安排:

  1. 复习+理解 泛型 K extends keyof 泛型 T
  2. 深入理解 K extends keyof any 【K extends keyof string |number |symbol
  3. 理解 P in K
    in 映射类型的关键字,用来遍历泛型K的所有属性
  4. 理解 K in keyof any [x: string] 可以代表[x: string] 也可以表示[x: number] [x: string]可以是字符串类型,数字类型 symbol类型
  5. 深入 Record 完成异步数据扁平化 【 实现方式1 】
text
	 type Record2<T> = {
			[x: string]: T,// 字符串索引可以是数字类型,可以是字符串类型,最终都会转换为字符串类型
		//[x: number]: T,// 字符串索引可以是数字类型 [x: number]可以最终合成一个数组的索引
		//[x:symbol]:T//索引签名参数类型必须为 "string" 或 "number"
	 }
  1. 深入 Record 完成异步数据扁平化 【 实现方式2 】

  2. object 和 Map 和 Record 区别 Record和object区别 区别1:Record 获取到是索引参数类型,所以可以赋初值为{},而object也可以,但是再次赋值 区别2: Record是泛型,获取值可以有自动提示功能,而object无法实现自动提示。

    实际开发为什么我们在显示数据,数据扁平化时用Record 原因1:是因为Record有多种实现方式,比如S100实现方式,Map就需要改底层源码才能做到【一般是不会改的】 原因2:Record是属于一个轻量级的type类型,Map相对Record是重量级,而且Map需要new出来的,所以要更加占用内存空间, 如果读取数据和显示数据频繁,就应该采用Record, 如果增删改比较多,那还是使用Map Record类型对于取出来的对象,可以自动提示输出对象的属性和方法

5-8 高级类型 Pick

本讲课程安排:

1 首先实现 Pick 快速抓取属性

Pick 主要用于提取某种数据类型的属性,但实际工作中,主要用来提取接口或 type 定义的对象类型中的属性

2 Pick+ Record 结合应用【真实应用场景】

5-10【 TS 高级 type 类型】 Partial+Required+ReadOnly
ts
// Partial 一次性全部变成可选选项的type高级类型
type Partial<T> = {
	[P in keyof T]?: T[P]
}

interface ButtonProps {
	type: 'button' | 'submit' | 'reset'
	text: string
	disabled: boolean
	onClick: () => void
}

const props: Partial<ButtonProps> = {
	text: "登录"
}

// Required 和Partial相反 一次性全部变成必选选项的type高级类型
type Required<T> = {
	[P in keyof T]-?: T[P]
}

//  ReadOnly 一次性全部变成可读选项的type高级类型
type ReadOnly<T> = {
	readonly [P in keyof T]: T[P]
}
5-11 【 TS 高级 type 类型】 环环相扣掌握 Omit 反向抓取属性数据 【真实应用场景】

Omit - 省略,忽略,去掉

本节课程安排:

(1) 理解 Exclude<keyof T, K>

(2) 理解 Pick<T, Exclude<keyof T, K>>

(3) 理解 type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

ts
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

interface Todo {
	title: string
	completed: boolean
	description: string
	// phone: number
}

type TodoPreview = Omit<Todo, "description">// type TodoPreview={}

const todo: TodoPreview = {
	title: 'Clean room',
	completed: false,
}

export {}

as- 重映射

Contributors

作者:Long Mo
字数统计:1.8k 字
阅读时长:6 分钟
Long Mo
文章作者:Long Mo
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Longmo Docs