typescript 泛型详解

typescript 泛型

泛型是可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于: 函数、接口、class中。
需求:创建一个id 函数,传入什么数据就返回该数据本身(也就是说,参数和返回值类型相同)。

function id(value: number): numberreturn value

比如,id(10)调用以上函数就会直接返回10 本身。但是,该函数只接收数值类型,无法用于其他类型为了能让函数能够接受任意类型,可以将参数类型修改为 any。但是,这样就失去了TS 的类型保护,类型不安全。

function id(value: any): any  return value }

泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用。实际上,在C#和lava等编程语言中,泛型都是用来实现可复用组件功能的主要工具之一

泛型是TypeScript中的一种工具,它允许你创建可重用的组件,这些组件可以在多种类型上工作,而不仅仅是一个类型。它们为你提供了一种方式来捕获类、接口或函数中的类型信息。

泛型函数

创建泛型函数
function id<Type>(value: Type): Type { return value }

tips:

  1. 语法:在函数名称的后面添加<>(尖括号),尖括号中添加类型变量,比如此处的Type
  2. 类型变量Type,是一种特殊类型的变量,它处理类型而不是值
  3. 该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)
  4. 因为Type是类型,因此可以将其作为函数参数和返回值类型,表示参数和返回值具有相同类型
  5. 类型变量Type可以是任意合法变量名称

调用泛型函数,

调用泛型函数方式很简单,在你调用泛型函数的时候用尖括号告诉ts你现在用的是啥类型值就好了

function id<Type>(value: Type): Type { return value }

// 声明一个number类型变量用于接收泛型函数id输出的参数
// 给泛型函数id传递一个number类型的参数10,它会返回一个number类型的值
let num: number = id<number>(10)

// 声明一个string类型变量用于接收泛型函数id输出的参数
// 给泛型函数id传递一个string类型的参数'hello', 它会返回一个string类型的值
let str: string = id<string>('hello')

tips

  1. 语法:在函数名称后面添加<>(尖括号),尖括号中指定具体的类型,比如上面的number类型
  2. 当传入number后,这个类型就会被函数声明时指定的类型变量Type捕获到
  3. 此时,Type的类型就是number,所以函数id参数和返回值的类型也都是number

同样的,当传入类型是string,函数id参数和返回值的类型就都是string
这样,通过泛型就做到了让id函数与多种不同的类型一起工作,实现了复用的同时保证了类型安全

使用类型推论,简化泛型函数的调用

如下示例
在这里插入图片描述

  1. 在调用泛型函数时,可以省略<类型>来简化泛型函数的调用
  2. 此时,TS内部会采用一种叫做类型参数推断机制,来根据传入的实参自动推断出类型变量Type的类型
  3. 比如,传入实参10,TS会自动推断出变量num的类型number,并作为Type的类型

tips: 更推荐这种简化的方式调用泛型函数,因为这样代码更短,更利于阅读(其实几乎所有的编程语言都是在声明的时候各种约束写起来复杂,但是调用的时候轻松)
但是当编译器无法推断类型或推断的类型不准确时,就需要显示的传入类型参数,
示例:比如一个最常见的,字面量类型推断
在这里插入图片描述
如上图,当输入的是一个字符串hello时,ts会推论出它是hello这种字面量类型,但是其实我们不是想要这种类型,我们是想要字符串类型,这时候就需要显示的传入类型参数,

泛型接口

泛型接口:接口也可以配合泛型来使用,以增加其灵活性,增强其复用性
示例如下
在这里插入图片描述
tips

  1. 在接口名称的后面添加<类型变量>,那么,这个接口就变成了泛型接口。
  2. 接口的类型变量,对接口中所有其他成员可见,也就是接口中所有成员都可以使用类型变量
  3. 使用泛型接口时,需要显式指定具体的类型 (比如,此处的ldFunc<nunber>)
  4. 此时,id方法的参数和返回值类型都是number;ids方法的返回值类型是number[]。

实际上js数组在ts中就是一个泛型接口,
示例如下
在这里插入图片描述
在这里插入图片描述

泛型类

泛型类:class也可以配合泛型来使用
比如 React的class组件的基类Component就是泛型类,不同的组件有不同的props和state

interface IState { count: number }
interface IProps { maxLength: number }
class InputCount extends React.Component<IProps, IState> {
 state: IState = { count: 0 }
  render() {
    return 
      <div>{ this.props.maxLength } < /div>
    }
}

tips React.Component 泛型类两个类型变量,分别指定props和state类型

创建泛型类

在这里插入图片描述
tips:

  1. 类似于泛型接口,在class名称后面添加<类型变量>这个类就变成了泛型类
  2. 此处的add方法,采用的是箭头形式的类型书写方式

创建泛型类实例
在这里插入图片描述
类似于泛型接口,在创建class实例时,在类名后面通过<类型>来指定明确的类型

泛型约束

泛型约束:默认情况下,泛型函数的类型变量Type可以代表多个类型,但是这也就导致了无法访问任何非公共类型属性
比如,id(‘abc’)正常来说调用函数时可以获取参数的长度,
在这里插入图片描述

这是因为当使用泛型时,TypeScript 无法确定传入的确切类型,因此它不会检查传入的类型是否具有 length 属性。这是因为在 TypeScript 中,任何类型都可以作为泛型参数,包括那些没有 length 属性的类型,比如 number。

错误提示如下
在这里插入图片描述
为了解决这个问题,我们可以为泛型参数添加约束,以限制其可能的类型。例如,如果你希望传入的类型是数组或字符串,因为这两种类型都有 length 属性,
如下实例
添加泛型约束收缩类型,主要有两种方式.

  1. 指定更加具体的类型
  2. 添加约束

示例如下
3. 指定更加具体的类型,
如下,将类型修改为Type,因为只要是数组,就一定存在length属性,因此就可以访问到length属性了
在这里插入图片描述

  • . 添加约束,
    首先,创建一个名为IsLength的接口,该接口要求实现它的对象必须具有length属性。接下来,通过让类型T继承该接口来进行约束,确保类型T也满足接口的要求。这样,泛型T也就具备了接口IsLength所定义的条件。

tips:因为number类型变量没有.length属性,所以现在再传number属性值时就会报错了
在这里插入图片描述

  1. 创建描述约束接口IsLength,该接口要求lenagth属性
  2. 通过extends关键字使用该接口,为泛型(类型变量)添加约束
  3. 该约束表示:传入的值必须具有length属性

tips : 传入的实参(比如,数组)只要length属性即可,

多个泛型变量约束

泛型的类型变量可以有多个,并且类型变量之间,还可以约束(比如第二个变量受第一个类型变量约束)
示例如下

	// 定义一个泛型函数 getProp。这个函数接收一个对象 obj 和一个键 key 作为参数。  
	// Type 是一个泛型,表示对象的类型。key extends keyof Type 表明 key 是 Type 的一个属性名。  
	// 这个函数返回 obj 对象上 key 键对应的值,这个值的类型是 Type[key]。  
	function getProp<Type, key extends keyof Type>(obj: Type, key: key): Type[key] {  
	  // 返回 obj 对象上 key 键对应的值。  
	  return obj[key];  
	}  
	  
	// 定义一个名为 person 的对象,该对象有两个属性,name 和 age。  
	let person = { name: '张三', age: 20 };  
	  
	// 调用 getProp 函数,传入 person 对象和 'name' 键,返回 person 对象的 'name' 属性的值。  
	// 这行代码的结果是 '张三'。  
	getProp(person, 'name')
  1. 添加了第二个类型变量 Key,两个类型变量之间使用 (,)逗号分隔
  2. keyof 关键字接收一个对象类型,生成其键名称 (可能是字符串或数字)的联合类型。
  3. 本示例中keyof Type 实际上获取的是person 对象所有键的联合类型,也就是:‘name|age’。
  4. 类型变量Key 受Type 约束,可以理解为: Key只能是Type 所有键中的任意一个,或者说只能访问对象中存在的属性。

泛型工具类

**泛型工具类型:**TS内置了一些常用的工具类型,来简化TS中的一些常见操作。说明:它们都是基于泛型实现的(泛型适用于多种类型,更加通用),并且是内置的,可以直接在代码中使用。这些工具类型有很多,常用的有以下几个:

  1. Partial<T>
  2. Readonly<T>
  3. Pick<T,keys>
  4. Record<Keys,T>
Partial<T> – 可选

泛型工具类-Partial用来构造(创建)一个类型,将T的所有属性设为可选
在这里插入图片描述
tips:通过Partial构造出来的新类型PartialProps结构和Props相同,但所有属性都变为可选的

如下,使用了Partial工具类的类实例可以让属性为空,但是没用Partial加工的类就不行
在这里插入图片描述

Readonly<T> – 只读

泛型工具类:Readonly<T>用来构造一个类型,将T的所有属性都设置为readonly(只读)
在这里插入图片描述
如下,使用Readonly工具类加工了的ReadonlyProps类的属性就都是只读的了
在这里插入图片描述

Pick<T,Keys> --keys属性构造新类型

泛型工具类Pick<T,Keys> 从T中选择一组属性来构造新类型

在这里插入图片描述
tips:

  1. pick工具类有两个类型变量,1.表示选择谁的属性,2. 表示选择那几个属性
  2. 其中第二个类型变量,如果只选择一个则只传入该属性名即可
  3. 第二个类型变量,如果只选择一个则只传入该属性名即可
  4. 构造出来的新类型PickProps只有id和title两个属性类型

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DP读书:社区文档(小白向)解读——iSulad 轻量级容器引擎功能介绍以及代码架构解析

10min带你快速了解iSulad 容器技术方案 功能介绍以及代码架构解析iSulad是啥iSulad怎么用:先看大佬咋说——maintainer李峰iSulad 轻量级容器引擎功能介绍以及代码架构解析iSulad提问iSulad_SIGiSulad的仓库&#xff1a; 主仓库嘿嘿 仓库链接&#xff1a;[https://gitee.com/op…

Java实现假日旅社管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统介绍2.2 QA 问答 三、系统展示四、核心代码4.1 查询民宿4.2 新增民宿评论4.3 查询民宿新闻4.4 新建民宿预订单4.5 查询我的民宿预订单 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的假日旅社…

JavaWeb学习|JSON与AJAX

学习材料声明 所有知识点都来自互联网&#xff0c;进行总结和梳理&#xff0c;侵权必删。 引用来源&#xff1a;尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版 JSON JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机…

两分钟秒懂Android控件设置

导言 本文从整体到局部,从常用布局(layout)到控件的设置,层层递进,一定要从前往后依次看 目录 1.常用布局方式 1.1 ConstraintLayout 约束布局 1.2 LinearLayout 线性布局 1.3 TableLayout 表格布局 1.4 GridLayout 瀑布布局 2.关于控件属性整合 2.1 放置位置 2.2 如…

cubeIDE之串口空闲中断注意事项

1&#xff1a;在配置完成后的main函数中不可使能接收中断 // __HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);//接收中断__HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);//空闲中断HAL_UART_Receive_DMA(&huart4,rx4_buffer, 255);//使能MDA接收HAL_UART_Transmit(&…

Linux系统中HTTP隧道的搭建与配置步骤:穿越网络的“魔法隧道”

在Linux系统中搭建HTTP隧道&#xff0c;就像是开启了一条穿越网络的“魔法隧道”。这条隧道能让你的数据在网络中自由穿梭&#xff0c;无论是远程办公还是数据同步&#xff0c;都能变得轻松自在。下面&#xff0c;就让我们一起探索如何搭建这条神奇的“魔法隧道”吧&#xff01…

2024-2-20-IO进程线程作业

1> 源代码&#xff1a; #include <myhead.h>int main(int argc, const char *argv[]) {pid_t pid -1;FILE *src NULL;FILE *dest NULL;if ((src fopen("./base.txt", "r")) NULL){perror("fopen error");return -1;}fseek(src, …

阿赵UE学习笔记——15、灯光的移动性概念和构建光照信息

阿赵UE学习笔记目录   大家好&#xff0c;我是阿赵。   继续学习虚幻引擎&#xff0c;这次来学习一下UE里面灯光的移动性概念和构建光照信息。 1、灯光移动性 打开一个带有灯光的场景 在大纲面板里面找到其中一个灯光&#xff1a; 会发现灯光的细节面板里面&#xff0c;…

Windows 自带的 Linux 子系统(WSL)安装与使用

WSL官网安装教程&#xff1a; https://learn.microsoft.com/zh-cn/windows/wsl/install Windows 自带的Linux子系统&#xff0c;比用VM什么的香太多了。可以自己看官方教程&#xff0c;也可以以下步骤完成。 如果中间遇到我没遇到的问题百度&#xff0c;可以在评论区评论&#…

【Python】【VS Code】VS Code中python.json和setting.json文件配置说明

目录 1. python.json配置 2. setting.json配置 3. 解决中文乱码 4. 实现效果 1. python.json配置 python.json 获取步骤&#xff1a;文件 -> 首选项 -> 配置用户代码片段 -> python 此为VS Code的头文件设置&#xff0c;复制以下内容到 python.json {"HEADER…

【字符串题目讲解】一文理解 Manacher Algoirth(马拉车算法)——以洛谷 P3805 和 P5446 为例

M a n a c h e r A l g o r i t h m \mathrm{Manacher\ Algorithm} Manacher Algorithm Manacher 算法主要是解决怎样的问题呢&#xff0c;其实是求解最长的回文串&#xff0c;但是只能找到长度为奇数的回文串&#xff0c;不过可以通过转化使得能够求解任意长度的回文串。 例…

【9】知识存储

一、图数据库neo4j Neo4j是一个高性能的,NOSQL图形数据库&#xff0c;它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎。单节点的服务器可承载上亿级的节点和关系&#xff0c;单节点性能不够时也可进行分布式集群部…

基于bloomz-7b指令微调的中文医疗问诊大模型,实现智能问诊、医疗问答

基于bloomz-7b指令微调的中文医疗问诊大模型&#xff0c;实现智能问诊、医疗问答 码源见文末 1.项目简介 本项目开源了基于医疗指令微调的中文医疗问诊模型&#xff1a;明医 (MING)。目前模型的主要功能如下&#xff1a; 医疗问答&#xff1a;对医疗问题进行解答&#xff0…

python 多线程+队列的简单应用

在实际处理需求的过程中&#xff0c;博主比较偏爱使用多线程threading 队列queue的方式 去开发代码。 &#xff08;本文注重的是搭建模板框架&#xff0c;仅供参考&#xff09; 举例&#xff1a; 以豆瓣电影的排行为例&#xff0c;写个简单的demo。 豆瓣链接&#xff1a;ht…

基于用Python对电商销售数据分析展示项目

项目背景 假设您有一个电商网站的销售数据集&#xff0c;包含用户购买记录、产品信息和销售时间等信息。您希望通过数据分析来找出哪些产品销售最好&#xff0c;以及哪些用户群体对哪些产品更感兴趣。 目录 项目背景 项目流程 数据收集和导入 数据集示例&#xff08;CSV格式…

IO 作业 24/2/20

一、思维导图 二、习题 #include <myhead.h> int main(int argc, const char *argv[]) {FILE *fpNULL;FILE *fqNULL;pid_t pidfork();if(pid>0){if((fpfopen("./text.txt","r"))NULL){perror("fopen error");return -1;} if((f…

【2024软件测试面试必会技能】Jmeter_性能测试(3):性能测试脚本的制作和调试

Charles Jmeter的性能测试脚本的制作和调试 以PHP论坛为例&#xff1a;http://47.107.178.45/phpwind/ Charles抓包 1、charles设置过滤&#xff1b;可参考&#xff1a;https://www.cnblogs.com/YouJeffrey/p/15334939.html 2、对于抓包操作进行备注 3、去掉资源文件&…

AS-V1000 视频监控平台产品介绍:客户端功能介绍(四)

目 录 一、引言 1.1 AS-V1000视频监控平台介绍 1.2平台服务器配置说明 二、软件概述 2.1 客户端软件用途 2.2 客户端功能 三、客户端功能说明 3.1告警管理 3.1.1告警联动 &#xff08;1&#xff09;告警联动显示 &#xff08;2&#xff09;告警联动处理 3…

Packet Tracer - 配置 IPv4 和 IPv6 接口

地址分配表 目标 第 1 部分&#xff1a;配置 IPv4 编址并验证连接第 2 部分&#xff1a;配置 IPv6 编址并验证连接背景信息 路由器 R1 和 R2 分别有两个 LAN。 您的任务是在每台设备上配置合适的编址并验证 LAN 之间的连接。 注&#xff1a;用户 EXEC 密码是 cisco。 特权 E…

单片机学习笔记---红外遥控红外遥控电机调速(完结篇)

目录 低电平触发中断和下降沿触发中断的区别 红外遥控 Int0.c Int.h Timer0.c Timer0.h IR.c IR.h main.c 红外遥控电机调速 Timer1.c Timer.h Motor.c Motor.h main.c 上一节讲了红外发送和接收的工作原理&#xff0c;这一节开始代码演示&#xff01; 提前说…