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.rhkb.cn/news/469175.html

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

相关文章

MySQL数据库:本地部署数据库以及安装彩虹猫【Navicat】

文章目录 一.安装前准备工作1.下载并解压文件2.修复电脑缺失的文件 二.本地部署MySQL1.先解压mysql-8.0.25-winx64.zip&#xff0c;并把文件放到安装需要的位置&#xff0c;再把my.ini文件放到mysql-8.0.25-winx64的根目录2.修改注册表的根目录信息为自己的安装装路径3.进命令符…

11个简单易用的电商购物车设计案例

文章目录 前言正文1.扁平化设计购物车2.无表格布局购物车3.美食购物车4.响应式购物车5.jQuery购物车6.动态价格更新购物车7.标签式滑动购物车8.动态商店与购物车一体化设计9.简约清爽的购物车设计10.基于Vue.js的购物车11.域名购物车 总结 前言 现在的电子商务网站&#xff0c…

Stable Diffusion Web UI - ControlNet 姿势控制 openpose

openpose 是 ControlNet 中常用的控制模式之一。 通过 openpose 可以锁定人物姿势&#xff0c;把姿势信息传递给 Stable Diffusion 扩散模型&#xff0c;让其在扩散生成图片的时候遵照特定的任务姿势。 通过 openpose 能够得到类似如下效果&#xff1a; 同样的姿势&#xff0…

Word2Vec,此向量维度,以及训练数据集单条数据的大小,举例说明;Skip-gram模型实现词嵌入;热编码(One-Hot Encoding)和词向量;

目录 Word2Vec Word2Vec,此向量维度,以及训练数据集单条数据的大小,举例说明 一、Word2Vec的词向量维度 二、训练数据集单条数据的大小 综上所述 热编码(One-Hot Encoding)和词向量 一、表示方式 二、维度与计算效率 三、语义捕捉能力 四、举例说明 Skip-gram模…

大模型预训练+微调大模型;大模型提示/指令模式”(Prompt/Instruct Mode)

目录 大模型发布版本 大模型参数量 预训练+微调大模型 预训练大模型的优势 微调的概念与过程 微调的优势 应用场景与案例 提示/指令模式”(Prompt/Instruct Mode) Prompt模式与Instruct模式的区别与联系 Prompt/Instruct模式的应用优势 应用案例 大模型发布版本 大…

WPF在MVVM模式下怎么实现导航功能

在mvvm的模式下wpf通过frame实现页面跳转_哔哩哔哩_bilibili 视频讲解同步可观看 如下图&#xff0c;我们要实现点击左侧的菜单&#xff0c;在右侧展示不同的页面 实现代码如下&#xff1a; 一、如何从主窗体跳转到页面。 1、在mainwindow.xaml的菜单栏代码里加入如下代码 …

ubuntu 22.04 server 安装 anaconda3

ubuntu 22.04 server 安装 anaconda3 https://www.anaconda.com/download/success Anaconda Installers wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh 其他的是 默认 Executing transaction: done installation finished. Do you wish to…

亚信安全新一代WAF:抵御勒索攻击的坚固防线

近年来&#xff0c;勒索攻击已成为黑客的主要攻击手段。新型勒索攻击事件层出不穷&#xff0c;勒索攻击形势愈发严峻&#xff0c;已经对全球制造、金融、能源、医疗、政府组织等关键领域造成严重危害。如今&#xff0c;勒索攻击手段日趋成熟、攻击目标愈发明确&#xff0c;模式…

函数式编程Stream流(通俗易懂!!!)

目录 1.Lambda表达式 1.1 基本用法 1.2 省略规则 2.Stream流 2.1 常规操作 2.1.1 创建流 2.1.2 中间操作 filter map distinct sorted limit ​编辑skip flatMap 2.1.3 终结操作 foreach count max&min collect anyMatch allMatch noneMatch …

SDL线程

文章目录 SDL线程相关 SDL线程相关 SDL线程创建&#xff1a;SDL_CreateThreadSDL线程等待: SDL_WaitThreadSDL互斥锁 :SDL_CreateMutex/SDL_DestoryMutexSDL锁定互斥: SDL_LockMutex/SDL_UnlockMutexSDL条件变量:SDL_CreateCond/SDL_DestoryCondSDL条件变量 等待通知: SDL_Con…

【初阶数据结构与算法】线性表之链表的分类以及双链表的定义与实现

文章目录 一、链表的分类二、双链表的实现1.双链表结构的定义2.双链表的初始化和销毁初始化函数1初始化函数2销毁函数 3.双链表的打印以及节点的申请打印函数节点的申请 4.双链表的头插和尾插头插函数尾插函数 5.双链表的查找和判空查找函数判空函数 6.双链表的头删和尾删头删函…

深 度 学 习

神经网络基础 一、逻辑回归( Logic Regression ) 1 问题的模型 模型&#xff1a; 其中xx为输入量&#xff0c;y^​预测量&#xff0c;σ()激活函数。   逻辑回归主要用于二分类问题的拟合&#xff1a;0≤y^P(y1∣x)≤1&#xff0c;σ(z)如图&#xff1a; ​ 问题&#xff…

【Leecode】Leecode刷题之路第46天之全排列

题目出处 46-全排列-题目出处 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 46-全排列-官方解法 预备知识 回溯法&#xff1a;一种通过探索所有可能的候选解来找出所有的解的算法。如果候选解…

解线性方程组(二)

实验类型&#xff1a;●验证性实验 ○综合性实验 ○设计性实验 实验目的&#xff1a;进一步熟练掌握用Jacobi迭代法和Gauss-Seidel法解线性方程组的算法&#xff0c;提高编程能力和解算线性方程组问题的实践技能。 实验内容&#xff1a; 1)取初值性x(0)(0,0,0,0)T, 精度要求ε…

ReactPress系列—NestJS 服务端开发流程简介

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎提出宝贵的建议&#xff0c;感谢Star。 NestJS 服务端开发流程简介 NestJS 是一个用于构建高效、可靠和可扩展的服务器端应用程序的框架。它使用 TypeScript&#xff08;但也支持纯 Java…

ImportError: cannot import name ‘packaging‘ from ‘pkg_resources‘ 的参考解决方法

文章目录 写在前面一、问题描述二、解决方法参考链接 写在前面 自己的测试环境&#xff1a; Ubuntu20.04 ROS-Noetic 一、问题描述 自己在通过 pip install 安装module时 &#xff08;使用的是 pip install mmcv&#xff09;遇到如下问题&#xff1a; ImportError: cannot …

运维人员必备的 Mac Zsh 配置技巧

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Flume学习

一、Flume概述 Flume最主要的作用就是&#xff0c;实时读取服务器本地磁盘的数据&#xff0c;将数据写入到HDFS。 二、Flume基础架构 三、Flume安装部署 配置Flume的前提是要配置好JDK和Hadoop 1.解压 [rootlxm148 soft]# tar -zxvf ./apache-flume-1.9.0-bin.tar.gz -C /…

FBX福币交易所多只高位股重挫,聚星科技首日高开348%

查查配分析11月11日电 周一,A股三大指数集体低开,沪指低开0.58%,深成指低开0.67%,创业板指低开0.99%。 FBX福币凭借用户友好的界面和对透明度的承诺,迅速在加密货币市场中崭露头角,成为广大用户信赖的平台。 Wind截图 券商股明显回调,大消费普遍走低,乳业、白酒、文旅板块跌幅…

基于matlab的人眼开度识别

我国已经成为世界汽车生产和制造大国&#xff0c;道路车辆的不断增加道路基础设施不断增强&#xff0c;但是随之而来的问题也日益严重&#xff0c;比如交通事故&#xff0c;噪声大气污染等。汽车行驶的安全性由于关乎人民生命安全&#xff0c;所以日益受到各国政府以及研究机构…