TypeScript泛型基础知识

1.1 泛型

泛型是可以在保证类型安全的前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class中。

需求:创建一个id函数,传入什么数据就返回该数据本身(也就是说,参数和返回值类型相同

function id(value:number):number {return value}

比如,id(10)调用以上函数就会直接返回10本身。但是,该函数只接收数值类型,无法用于其他类型

为了能让函数接收任意类型,可以将参数类型修改为any。但是,这样就失去了TS的类型保护,类型不安全

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

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

1.2 创建泛型

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

解释:

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

1.3 调用泛型函数

function id<Type>(value:Type):Type {return value}
//调用
const num = id<number>(10)
const str = id<string>('a')
//函数类型Type,传入参数Value类型:Type,返回值类型:Typefunction id<Type>(Value:Type):Type{return Value
}const num=id<number>(10)
console.log(num)
//String类型
function id2<Type>(Value:Type):Type{return Value}
const num2=id2<string>("哈哈哈")
console.log(num2)

解释:

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

同样,如果传入类型string,函数id参数和返回值的类型就都是string

这样,通过泛型就做到了让id函数与多种不同类型一起工作,实现了复用的同时又同时保证了类型安全

1.4 简化调用泛型函数

简化调用泛型函数:

function id<Type>(value):Type {
return value
}let num=id<number>(10)
//可以改进为
let num=id(10)

解释:

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

推荐:使用这种简化的方式调用泛型函数,使代码更短,更易于阅读

说明:当编译器无法推断类型或者推断的类型不准确时,就需要显式的传入类型参数

简化调用泛型函数和调用泛型函数有以下区别,当鼠标放上去,简化调用泛型函数

image-20241113183513902

1.5 泛型约束

泛型约束:默认情况下,泛型函数的类型变量Type可以代表多个类型,这导致无法访问任何属性

比如id(‘a’)调用函数时获取参数的长度

function id<Type>(value:Type):Type {console.log(value.length)//这块length会爆红return value
}

解释:Type可以代表任意类型,无法保证一定纯在length属性,比如number类型就没有length

此时,就需要为泛型添加约束来收缩类型(缩窄类型取值范围)

添加泛型约束收缩类型,主要有以下两种方式:1. 制定更加具体的类型 2.添加约束

  1. 指定更加具体的类型
function id<Type>(value:Type[]):Type[] {
console.log(value.length)return value
}

比如,将类型修改为Type[] (Type类型的数组),因为只要是数组就一定存在length属性,因此就可以被访问了

//参数里面的Type不用改
function id<Type>(value:Type[]): Type[]{value.lengthreturn value
}

image-20241113184940037

改变类型为type[]

image-20241113185006185

为什么要添加泛型约束呢?

如果你不添加类型约束,咱们得类型变量Type呢就表示任意的类型的,因此就导致这个类型的变量去访问任何的属性,没法进行任何的操作

  1. 添加约束
interface Ilength {length:number}
function id<Type extends ILength>(value:Type):Type {//此处的extends就不代表继承了,代表要满足后面类型的要求console.log(value.length)return value
}

解释:

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

注意:传入的实参(比如,数组)只要有length属性即可,这也符合前面讲到的接口的类型兼容性

interface Ilength {length:number}
//此处的extends表示满足ILength里面的类型约束
function id<Type extends Ilength>(value:Type):Type {value.lengthreturn value
}
let num=id(['a','c'])
let num1=id("abcdf")
let num2=id({length:10,name:'jack'})
console.log(num,num1,num2)
//错误演示:id(123)

1.6 多个泛型变量的情况

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

比如创建一个函数来获取对=对象中属性的值:

function getProp<Type,key extends keyof Type>(obj:Type,key:Key) {return obj[key]
}
let person = {name:'jack',age:18}
getProp(person,'name')

解释:

  1. 添加了第二个类型变量Key,两个类型变量之间使用(,)逗号分隔
  2. keyof关键字接收一个对象类型,生成其键名称(可能是字符串或数字)的联合类型
  3. 本实例中keyof Type 实际上获取的是person对象所有键的联合类型,也就是:‘name’|‘age’
  4. 类型变量key受Type约束,可以理解为:key只能是Type所有键中的任意一个,或者说只能访问对象中存在的属性

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

多线程的安全问题

什么是线程安全问题&#xff1f; 多个线程&#xff0c;访问同一资源&#xff0c;出现了问题&#xff0c;就是线程安全问题&#xff08;数据不准确&#xff0c;或者直接报错&#xff09; 1&#xff09;错误演示&#xff1a; public class Demo04 {static int tickedNum 100;/…

推荐一套相片复原工具:Focus Magic

Focus Magic是一套相片复原工具&#xff0c;能够帮助你修补及强化那些模糊不清楚的影像。其他那些锐利化工具只能够修补那些只有一点模糊的相片&#xff0c;但有了Focus Magic你就可以把那些根本完全没对准焦距的相片重新对准焦距。程序还可以以插件的形式作为其他图形处理工具…

C++:类的继承

在C中&#xff0c;类的继承是一种面向对象编程&#xff08;OOP&#xff09;的重要特性&#xff0c;它允许一个类&#xff08;子类或派生类&#xff09;继承另一个类&#xff08;基类或父类&#xff09;的属性和方法。通过继承&#xff0c;可以重用现有的代码&#xff0c;减少重…

详细解读Gson 、Jackson 、FastJson 三大json序列化工具

一 gson Google提供的用来java对象和JSON数据之间进行映射的JAVA类库 优缺点 优点&#xff1a;快速、高效&#xff0c; 依赖少只有一个jar包&#xff0c;面向对象&#xff0c;数据传输解析方便 缺点&#xff1a;速度较慢 mvn依赖 <dependency><groupId>com.go…

版块控制---git

引入 设想&#xff0c;当我们写论文时&#xff0c;对第一版不够满意时&#xff0c;想做出修改但是又怕修改时回毁掉整个论文版本&#xff0c;所以我们通常会进行备份&#xff0c;以防止数据被修改后的崩毁&#xff0c;版块控制就是这个合理创建管理备份的过程&#xff0c;而且这…

BLE 蓝牙客户端和服务器连接

蓝牙通信在设计小型智能设备时非常普遍&#xff0c;之前一直没有使用过&#xff0c;最近使用ardunio ESP32 做了一些实验&#xff0c;做了一个收听播客的智能旋钮&#xff08;Smart Knob&#xff09;&#xff0c;它带有一个旋转编码器和两个按键。 本文介绍BLE 服务器Server和W…

图(Graph)的概念和遍历

目录 定义 相关概念 无向图&#xff08;Undirected graphs) 有向图&#xff08;Directed graphs&#xff09; 完全图 稀疏图 稠密图 权&#xff08;Weight&#xff09; 网&#xff08;Network&#xff09; 子图&#xff08;Subgraph&#xff09; 图的顶点与边间关系 …

python成长技能之正则表达式

文章目录 一、认识正则表达式二、使用正则表达式匹配单一字符三、正则表达式之重复出现数量匹配四、使用正则表达式匹配字符集五、正则表达式之边界匹配六、正则表达式之组七、正则表达式之贪婪与非贪婪 一、认识正则表达式 什么是正则表达式 正则表达式&#xff08;英语&…

Unity图形学之RenderQueue

1.指定物体的渲染顺序 Tags { “Queue” “XXXX” } 取值类型&#xff1a; Background&#xff1a; 对应数值为 1000&#xff0c;用于需要被最先渲染的对象&#xff0c;。 Geometry&#xff1a; 对应数值为 2000, 用于不透明的物体。这个是默认的选项&#xff08;如果不指明…

i春秋-破译(凯撒密码+数字替换单词中的字母)

练习平台地址 竞赛中心 题目描述 题目内容 就是破译&#xff01;&#xff01;&#xff01; 解题 观察到最后一段是四个字母加上{xxxxx}的形式&#xff0c;很像flag&#xff0c;我们猜测要破译的主要是这个片段 大括号依然存在&#xff0c;那么可能是通过凯撒密码来加密的&a…

丹摩征文活动|平台评测与使用体验报告

一、基本信息 目标产品 丹摩智算平台www.damodel.com 体验设备 台式机 体验系统/环境 Windows 10/浏览器 体验时间 2024/11 二、产品信息 产品类型&#xff1a;云计算服务提供商 产品定位&#xff1a;提供AI开发和算力GPU租赁服务的平台。它旨在简化AI开发流程&#…

Stable Diffusion核心网络结构——CLIP Text Encoder

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…

20241118给荣品PRO-RK3566开发板刷Rockchip原厂的buildroot后使用iperf3打流

20241118给荣品PRO-RK3566开发板刷Rockchip原厂的buildroot后使用iperf3打流 2024/11/18 16:38 缘起&#xff0c;使用荣品的DTS。 Y:\RK3566_RK3568_Linux5.10_V1.2.0\device\rockchip\.chips\rk3566_rk3568\rockchip_rk3566_evb2_lp4x_v10_defconfig 1、指定RK_KERNEL_DTS_NAM…

基于java+SpringBoot+Vue的基于web的智慧社区设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven mysql5.7或8.0等等组成&#x…

分析一个库 便于以后的使用 WiFiManager.h 2024/11/18

这一段是开启服务器 的 这些都不是重点 重点是那个R_update ,没猜错的话应该是升级的功能 直接索引到定义看看 ,很明显这里是设置了一个 web 访问地址 那就只有换个思路往后查找 handleUpdate 找到这个函数定义 void WiFiManager::handleUpdate() {#ifdef WM_DEBUG_LEVELDEBUG…

学习笔记024——Ubuntu 安装 Redis遇到相关问题

目录 1、更新APT存储库缓存&#xff1a; 2、apt安装Redis&#xff1a; 3、如何查看检查 Redis版本&#xff1a; 4、配置文件相关设置&#xff1a; 5、重启服务&#xff0c;配置生效&#xff1a; 6、查看服务状态&#xff1a; 1、更新APT存储库缓存&#xff1a; sudo apt…

【MySQL系列】深入理解MySQL中的存储、排序字符集

前言 在创建数据库时&#xff0c;我们经常会需要填写数据库的所用字符集、排序规则&#xff0c;字符集和排序规则是两个非常重要的概念&#xff0c;它们决定了数据库如何存储和比较字符串数据。在 MySQL 中&#xff0c;常用的存储字符集有 utf8、utf8mb4&#xff0c;而排序字符…

tcp 超时计时器

在 TCP&#xff08;传输控制协议&#xff09;中有以下四种重要的计时器&#xff1a; 重传计时器&#xff08;Retransmission Timer&#xff09; 作用&#xff1a;用于处理数据包丢失的情况。当发送方发送一个数据段后&#xff0c;就会启动重传计时器。如果在计时器超时之前没有…

Docker部署ES7.9.3单节点

Elasticsearch&#xff08;简称ES&#xff09;是一个分布式、可扩展、实时的搜索与数据分析引擎&#xff01; Elasticsearch位于Elastic Stack核心&#xff0c;为所有类型的数据提供近乎实时的搜索和分析。无论是结构化或非结构化文本、数字数据还是地理空间数据&#xff0c;El…