TypeScript 类型进阶指南

上篇文章讲述了泛型的基础用法,下面是关于 TypeScript 泛型的一些高级知识点,简单介绍一下。

1. 条件类型中的泛型约束

条件类型 (T extends U ? X : Y) 是 TypeScript 的一种高级特性,它根据类型的条件返回不同的结果。这种约束在泛型中非常实用,可以根据 传入的类型 动态生成 结果类型。

使用场景:用于校验参数类型,例如动态生成函数响应类型,或在表单校验中提供不同的返回值提示。

🌰

type IsString<T> = T extends string ? 'yes' : 'no';type Result1 = IsString<number>; // "no"
type Result2 = IsString<string>; // "yes"

例子中,如果 T 是 string 类型,则 IsString<T> 返回 "yes",否则返回 "no"。

2. 分布式条件类型

当类型参数是联合类型时,条件类型会对联合类型的每个成员逐一应用条件,这称为分布式条件类型

使用场景:常用于过滤联合类型的成员。例如,在权限校验或数据解析中,排除不符合条件的类型成员。

🌰

type ExcludeStringOrNumber<T> = T extends string | number ? never : T;type Result = ExcludeStringOrNumber<string | boolean | number>; // boolean

例子中,T 被分解为 string、boolean 和 number,每个成员分别应用条件类型,然后合并结果。此处,string 和 number 被过滤掉,最终返回 boolean 类型。这种特性允许对联合类型的每个成员单独处理。

3. 递归泛型类型

TypeScript 支持通过递归来定义类型,在处理树形结构或嵌套数据时非常有用。

使用场景:用于定义无限嵌套的数组或对象类型,例如在 JSON 数据解析中动态定义嵌套数据的类型。

🌰

type Nested<T> = T | Nested<T>[];const data: Nested<string> = ['hello', ['world', ['!']]]; // 嵌套字符串数组

递归泛型 Nested<T> 可以处理无限层次的嵌套数据,确保每层嵌套的元素类型一致。

4. 分布式条件类型

在 TypeScript 中,条件类型会在联合类型上自动分发。具体来说,当条件类型的左侧是一个泛型参数(如 T),且 T 是联合类型时,TypeScript 会将每个联合成员单独放在条件类型中进行计算,并最终合并结果。这种特性被称为 分布式条件类型

分布式条件类型是一种对联合类型的每个组成部分单独应用条件逻辑的特性。在处理复杂类型推断和条件判断时非常有用。

当 T 是一个联合类型(如 string | number)时,TypeScript 会对联合类型的每个成员分别应用条件类型逻辑,而不是直接应用到整个联合类型上。

🌰:定义一个类型

type MyType<T> = T extends string ? '字符串类型' : '非字符串类型';type Result = MyType<string | number>;

变成了联合类型 string | number,所以 MyType<T> 会自动分解为:

MyType<string> | MyType<number>

然后对每个成员单独应用条件判断:

MyType<string>:string 满足 T extends string 的条件,返回 '字符串类型'。

MyType<number>:number  不满足 T extends string 的条件,返回 '非字符串类型'。

最终结果是:

type Result = '字符串类型' | '非字符串类型';

5. Mapped Types 与泛型组合

映射类型 是 TypeScript 的特性,允许对一个对象类型的每个属性进行操作。这种操作可以是增加属性修饰符(如 只读、可选)、更改属性值类型、重命名等。结合泛型,映射类型可以动态地根据输入类型生成新类型。

可读:🌰

type ReadonlyType<T> = {readonly [P in keyof T]: T[P];
};interface User {name: string;age: number;
}type ReadonlyUser = ReadonlyType<User>; // 所有属性变为只读 { readonly name: string; readonly age: number; }

keyof T 表示类型 T 的所有键组合的联合类型,[P in keyof T] 是对 T 类型的每个键 P 进行一次遍历,这种遍历称为“映射类型”,将对象的每个属性逐一映射到新类型中。

T[P] 表示 T 类型中键 P 对应的值的类型,也就是说,对于每个 P,保持其类型不变。

ReadonlyType<T> 会将对象的每个属性设置为只读。

可选:🌰

type OptionalType<T> = {[P in keyof T]?: T[P];
};type OptionalUser = OptionalType<User>;

6. 键值联合 (Key Remapping)

TypeScript 4.1 引入的键值联合特性,可以在映射类型中重映射键名。

使用场景:应用于从外部 API 获取数据并需要重命名字段名的场景。也可用于前端动态合成自定义字段。

🌰

type MappedType<T> = {[K in keyof T as `new_${K & string}`]: T[K];
};interface User {name: string;age: number;
}type NewUser = MappedType<User>; // { new_name: string; new_age: number }

这里,键值映射允许为 keyof T 的每个键加上 new_ 前缀,这种方法在重命名或动态合成属性名时非常有用。

7. infer 关键字

在 TypeScript 中,infer 常用在条件类型中,用于在类型推导过程中“推测”类型的一部分。它允许我们在复杂类型中提取出一部分类型信息并将其存储到一个局部类型变量中,可以对其进一步操作。这个特性在处理函数的参数类型、返回类型,或者对复杂数据结构进行类型提取时非常有用。

7.1 基本原理
// 基本格式
T extends SomeType<infer U> ? X : Y

- infer U:如果 T 满足 SomeType 的条件,那么 U 就是从 SomeType 中提取的类型。U 类型是一个局部变量,可以在条件类型的 true 分支(即 X)中使用。

- X 和 Y:是条件类型的返回值,根据 T 是否符合条件决定使用哪个分支。

🌰:假设有一个函数类型 (x: number) => string,希望提取它的返回类型,可以使用 infer 来实现。

type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never;type MyFunction = (x: number) => string;
type Result = ReturnTypeOf<MyFunction>; // Result 被推导为 string

在上面的例子中,T 是传入的类型,如果 T 是一个函数类型(符合 (...args: any[]) => infer R 的形式),那么 提取 R 为返回类型。在 Result 中,返回类型为 string。

7.2 常见应用场景

1、提取函数的参数类型,生成一个包含所有参数类型的元组。

🌰

type ParametersOf<T> = T extends (...args: infer P) => any ? P : never;function greet(name: string, age: number): string {return `Hello ${name}, you are ${age} years old.`;
}type GreetParameters = ParametersOf<typeof greet>; // [string, number]

ParametersOf<T>:如果 T 是一个函数类型,则返回该函数的参数类型组成的元组 P。

2、提取 Promise 的返回值类型

🌰

type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;type Result1 = UnwrapPromise<Promise<number>>; // number
type Result2 = UnwrapPromise<number>; // number(非 Promise 类型,直接返回 T)

UnwrapPromise<T>:检查 T 是否为 Promise<infer U> 类型,如果是,则返回 U。

3、从嵌套结构中提取类型

在复杂的数据结构(例如嵌套数组、对象等)中,可以使用 infer 逐层提取出某个目标类型。

🌰

type ElementType<T> = T extends (infer U)[] ? U : T;type Result1 = ElementType<number[]>; // number
type Result2 = ElementType<string[][]>; // string
type Result3 = ElementType<boolean>; // boolean

ElementType<T>:检查 T 是否为数组类型 (infer U)[],如果是,则返回数组元素类型 U。

总结

以上是一些关于泛型复杂的知识点,包括条件类型、递归泛型和键值联合等特性,为 TypeScript 提供了丰富的类型控制能力,使代码更具复用性。简单介绍一下,大家感兴趣的话可以深入了解一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60025.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AUTOSAR CP Ethernet State Manager(EthSM)规范的主要功能以及工作原理导读

AUTOSAR Ethernet State Manager&#xff08;以下简称EthSM&#xff09;规范的主要功能 AUTOSAR Ethernet State Manager&#xff08;以下简称EthSM&#xff09;规范的主要功能包括&#xff1a; 通信控制 网络模式管理&#xff1a;为通信管理器&#xff08;ComM&#xff09;提…

深度学习中的感受野:从基础概念到多层次特征提取

在深度学习&#xff0c;特别是计算机视觉任务中&#xff0c;感受野&#xff08;Receptive Field&#xff09;是一个至关重要的概念。它指的是在神经网络中某一层的神经元在输入图像上“看到”的区域大小。感受野的大小影响了网络能捕捉的特征层级&#xff0c;从而决定了它的特征…

VirtIO实现原理(1)

本文内容参考: VirtIO实现原理——PCI基础_virtio-pci-CSDN博客 QEMU源码全解析 —— virtio(3)_qemu virtio block bus-CSDN博客 特此致谢! 序言 本系列文章是笔者在看了网名为“享乐主”的VirtIO系列文章后决心要写的。这位博主的“VirtIO专栏”中博文的内容从技术层…

2024年双11激光投影仪哪个品牌最好?当贝新品震撼视觉的秘密武器

激光投影仪逐渐占据家庭娱乐生活的中心位置&#xff0c;以其超大屏优势与卓越的性能获得了众多消费者的青睐。双11购物狂欢节期间&#xff0c;正是入手一台高品质激光投影仪的好时机&#xff0c;各大厂商也纷纷推出了品牌新品&#xff0c;2024年双11激光投影仪怎么选&#xff1…

React的概念以及发展前景如何?

React是一个由Facebook开发的用于构建用户界面的的开源JavaScript库&#xff0c;它主要用于构建大型、动态的Web应用程序。React的主要特点是使用VirtualDOM&#xff08;虚拟DOM&#xff09;来优化性能&#xff0c;并使用声明式的编程方式来编写UI。 React的主要概念包括&#…

定位,堆叠,CSS精灵,过渡,光标(前端)

一.定位 1.作用 灵活改变盒子在网页中的位置 2.标签 position 3.属性值 &#xff08;1&#xff09;相对定位relative relative&#xff08;相对定位&#xff09;-----改变位置的参照物是原来的位置&#xff0c;挪动后原来的位置不托标&#xff0c;不被占用。 要配合top…

2024-11-01 - 统一身份认证 - OpenLdap - 中间件 - 流雨声

摘要 2024-11-01 周五 杭州 暴雨 调查问卷: https://www.wjx.cn/vm/exIBFDM.aspx# 2024年转瞬即逝&#xff0c;可是生活还在继续&#xff0c;这里有一项关于人工智能和项目管理对于效能关系的调研问卷&#xff0c;AI 对工作的作用和影响。问卷不采集个人信息&#xff0c;在此…

【363】基于springboot的高校竞赛管理系统

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…

qt QTextFrame详解

1. 概述 QTextFrame是Qt框架中用于表示文本框架的类。它允许在QTextDocument中创建和管理具有特定边界和格式的文本区域。QTextFrame可以包含文本、图像、表格或其他QTextFrame&#xff0c;从而提供丰富的文本布局和排版功能。QTextFrame通常与QTextCursor结合使用&#xff0c…

【JWT】Asp.Net Core中JWT刷新Token解决方案

Asp.Net Core中JWT刷新Token解决方案 前言方案一:当我们操作某个需要token作为请求头的接口时,返回的数据错误error.response.status === 401,说明我们的token已经过期了。方案二:实现用户无感知的刷新token值,我们希望当响应返回的数据是401身份过期时,响应阻拦器自动帮我…

如何在Microsoft Edge中删除已保存的网站密码

目录 前言1. 如何进入Edge的密码管理界面1.1 打开Microsoft Edge的设置菜单1.2 进入个人资料设置1.3 进入密码管理 2. 在Edge中查看和删除已保存的密码2.1 查找需要删除的密码2.2 检查密码安全性2.3 删除特定网站的密码 3. 提升Edge密码管理的安全性3.1 启用Edge的多重身份验证…

[ Linux 命令基础 4 ] Linux 命令详解-文本处理命令

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Linux 实验:日志的备份与恢复 xfs文件系统

添加一个新的硬盘&#xff0c;创建硬盘分区sdc1 设置文件系统格式xfs&#xff0c;提示安装xfsprogs&#xff0c;如果安装失败&#xff0c;在后缀加上--fix-missing直到安装完成为止 mkdir创建空目录data&#xff0c;将sdc1挂载到data&#xff0c;data是根目录下新建的目录&…

【C#】使用.net9在C#中向现有对象动态添加属性

在 C# 中向现有对象动态添加属性并不像在 Python 或 JavaScript 中那样容易&#xff0c;因为 C# 是一种强类型语言。 但是&#xff0c;我们可以通过使用一些技术和库来实现这一点&#xff0c;例如扩展方法、字典等。本文将详细介绍如何在 C# 中实现这一点。ExpandoObject 方法 …

Python学习从0到1 day26 第三阶段 Spark ⑤ 搜索引擎日志分析

目录 一、搜索引擎日志分析 二、需求1&#xff1a;热门搜索时间段(小时精度)Top3 实现步骤 三、需求2&#xff1a;打印输出:热门搜索词Top3 实现步骤 四、需求3&#xff1a;打印输出:统计hadoop关键字在哪个时段被搜索最多 实现步骤 五、需求4&#xff1a;将数据转换为JSON格式…

#渗透测试#SRC漏洞挖掘#深入挖掘CSRF漏洞01

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

揭秘云计算 | 2、业务需求推动IT发展

揭秘云计算 | 1、云从哪里来&#xff1f;-CSDN博客https://blog.csdn.net/Ultipa/article/details/143430941?spm1001.2014.3001.5502 书接上文&#xff1a; 过去几十年间IT行业从大型主机过渡到客户端/服务器&#xff0c;再过渡到现如今的万物互联&#xff0c;IT可把控的资…

Grover算法——量子搜索算法

假设N个数据中符合条件的数据有M个&#xff0c;则量子搜索算法的复杂度为&#xff0c;远小于经典算法的复杂度。 黑箱 下面以N2为例&#xff0c;介绍黑箱如何标记符合条件的数据。N2意味着只有两个数据&#xff0c;可以用0和1来表示这两个数据&#xff0c;也就只需要一个量子比…

Ubuntu24.04网络异常与应对方案记录

PS: 参加过408改卷的ZJU ghsongzju.edu.cn 开启嘲讽: 你们知道408有多简单吗&#xff0c;操作系统真实水平自己知道就行&#xff5e;&#xff5e; Requested credits of master in UWSC30&#xff0c;in ZJU24&#xff0c;domestic master is too simple ubuntu安全软件 在 U…

智能的编织:C++中auto的编织艺术

在C的世界里&#xff0c;auto这个关键字就像是一个聪明的助手&#xff0c;它能够自动帮你识别变量的类型&#xff0c;让你的代码更加简洁和清晰。下面&#xff0c;我们就来聊聊auto这个关键字的前世今生&#xff0c;以及它在C11标准中的新用法。 auto的前世 在C11之前&#x…