TypeScript中泛型的详细介绍

在TypeScript(TS)中,泛型(Generics)是一种强大的特性,它允许在定义函数、接口或类时不预先指定具体的类型,而是在使用的时候再指定类型。这种参数化类型的方式使得代码更加灵活和可复用。

2.1. 泛型的定义与用途

泛型本质上是一种类型参数,它代表了一个可以在使用阶段被具体类型替换的占位符。通过泛型,可以编写出能够处理多种不同数据类型的函数、接口或类,而无需为每种数据类型编写单独的实现。这不仅提高了代码的复用性,还增强了类型安全性。

2.2. 泛型的应用场景

  1. 泛型函数:在定义函数时,可以使用泛型来指定参数和返回值的类型。这样,在调用函数时,可以传入具体的类型参数,从而确保函数参数和返回值的类型安全。
  2. 泛型接口:接口也可以使用泛型来定义。这允许接口包含未指定的类型参数,这些参数在使用接口时被具体化。通过泛型接口,可以定义出更加灵活和通用的数据结构。
  3. 泛型类:类也可以使用泛型来定义。在类定义中,可以指定一个或多个类型参数,这些参数在类的实例化和方法调用时被具体化。泛型类提供了更加灵活和类型安全的类定义方式。

2.3. 泛型约束

在泛型编程中,有时需要对泛型参数进行约束,以确保它们符合特定的类型结构。这可以通过使用extends关键字来实现。例如,可以定义一个泛型约束接口,并在泛型定义中使用extends来限制泛型参数必须实现该接口。这样,在泛型函数或类中就可以安全地访问该接口定义的属性和方法。

2.3.1. 泛型函数中的约束
2.3.1.1. 例子1:约束泛型参数必须具有某个属性
interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;
}// 调用泛型函数
const obj = { length: 10, name: "example" };
loggingIdentity(obj); // 输出: 10

在这个例子中,泛型T被约束为必须实现Lengthwise接口,这意味着它必须包含一个length属性。因此,在函数内部可以安全地访问arg参数的length属性。

2.3.1.2. 例子2:约束泛型参数为特定类型的数组
function sum<T extends number[]>(numbers: T): number {return numbers.reduce((acc, curr) => acc + curr, 0);
}// 调用泛型函数
const nums = [1, 2, 3, 4];
console.log(sum(nums)); // 输出: 10

在这个例子中,泛型T被约束为必须是一个数字类型的数组。这确保了reduce方法中的累加操作是安全的,因为数组中的每个元素都是数字。

2.3.2. 泛型接口中的约束
2.3.2.1. 例子3:约束泛型接口的实现者必须包含某个属性
interface Box<T> {contents: T;
}interface BoxWithLength extends Box<any> {length: number;
}// 实现泛型接口并满足约束
class StringBox implements BoxWithLength {contents: string;length: number;constructor(contents: string) {this.contents = contents;this.length = contents.length;}
}// 使用实现类
const box = new StringBox("Hello, TypeScript!");
console.log(box.contents); // 输出: Hello, TypeScript!
console.log(box.length);   // 输出: 19

在这个例子中,BoxWithLength接口继承自Box<any>接口,并添加了length属性作为约束。StringBox类实现了BoxWithLength接口,并满足了其约束条件。

2.3.3. 泛型类中的约束
2.3.3.1. 例子4:约束泛型类的类型参数
class Pair<T extends number | string> {first: T;second: T;constructor(first: T, second: T) {this.first = first;this.second = second;}
}// 使用泛型类
const numberPair = new Pair<number>(1, 2);
const stringPair = new Pair<string>("Hello", "World");// 尝试使用不满足约束的类型(会导致编译错误)
// const booleanPair = new Pair<boolean>(true, false); // 错误:布尔类型不满足泛型约束

在这个例子中,泛型类Pair的类型参数T被约束为只能是数字或字符串类型。这确保了firstsecond属性的类型是一致的,并且只能是数字或字符串。

2.3.4. 总结

泛型约束在TypeScript中是一种强大的特性,它允许在定义泛型时指定类型参数必须满足的条件。通过合理使用泛型约束,可以编写出更加类型安全、功能强大和可复用的泛型代码。以上例子展示了在不同场景下如何使用泛型约束来增强代码的类型安全性和可复用性。

2.4. 泛型与默认类型

在TypeScript中,还可以为泛型参数指定默认类型。这样,在调用泛型函数或创建泛型类的实例时,如果没有明确指定类型参数,就会使用默认类型。这提供了一种更加简洁和灵活的泛型使用方式。

2.5. 示例代码

以下是一个简单的泛型函数示例,它接受一个包含length属性的对象,并返回该对象:

interface Lengthwise {length: number;
}
// 使用泛型约束限制类型参数必须实现lengthwise接口
function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;
}// 调用泛型函数
const obj = { length: 10, name: "example" };
loggingIdentity(obj); // 输出: 10

在这个示例中,泛型T被约束为必须实现Lengthwise接口,这意味着它必须包含一个length属性。因此,在函数内部可以安全地访问arg参数的length属性。

综上所述,泛型是TypeScript中一种非常重要的特性,它允许在定义函数、接口或类时使用参数类型的占位符,从而增加代码的灵活性和复用性。通过合理使用泛型,可以编写出更加通用、可维护和类型安全的代码。

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

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

相关文章

4.4.5 timer中断流向Linux(从interrupt log回放)

4.4.5 timer中断流向Linux&#xff08;从interrupt log回放&#xff09; 按上文所述&#xff0c;timer中断3已经记录到root domain的interrupt log。在《3.4.1.3 IPIPE interrupt log数据结构》中&#xff0c;已经讨论过interrupt log的记录与回放。本小结&#xff0c;讨论什么…

WinDefender Weaker

PPL Windows Vista / Server 2008引入 了受保护进程的概念&#xff0c;其目的不是保护您的数据或凭据。其最初目标是保护媒体内容并符合DRM &#xff08;数字版权管理&#xff09;要求。Microsoft开发了此机制&#xff0c;以便您的媒体播放器可以读取例如蓝光&#xff0c;同时…

基于redis完成延迟队列

添加依赖 使用redisson完成延迟队列效果 <!-- redisson依赖 --><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.17.4</version> <!-- 请使用最新版本 --></dependency&g…

星辰资讯 | TiDB v7.5.4 v8.4.0 发版

作者&#xff1a; ShawnYan 原文来源&#xff1a; https://tidb.net/blog/6e299751 TiDB 8.4.0 DMR 发版 11 月 11 日&#xff0c;TiDB 8.4.0 版本发布&#xff0c;以下是该版本的一些关键特性和改进&#xff1a; 性能 分区表全局索引成为正式功能 &#xff1a;提高检索…

Spring基础

Spring基础 目录&#xff1a; 一、Spring框架简介 二、Spring容器机制 一、Spring框架简介 1. Spring发展历程 •在Spring兴起之前&#xff0c;Java企业级开发主要通过EJB (Enterprise JavaBean)完成。EJB是服务器端的组件模型&#xff0c;由于它过于依靠EJB容器&#xf…

二分查找法(leetcode 704)

在一个数组里找一个target&#xff0c;判断这个target在不在这个数组里&#xff0c;如果在&#xff0c;返回这个数组所对应的这个元素所对应的下标&#xff0c;否则返回-1. 易错点&#xff1a; &#xff08;1&#xff09;while(left<right) vs while(left<…

python的matplotlib实现数据分析绘图

目录 需求 效果 数据分析绘图示例 代码解释 运行结果 需求 分析一个班级中学生成绩分布&#xff0c;并绘图 效果 数据分析绘图示例 import matplotlib.pyplot as plt import numpy as np# 假设的学生成绩数据 np.random.seed(0) # 设置随机种子以确保结果可复现 score…

STM32电源管理—实现低功耗

注&#xff1a; 本文是学习野火的指南针开发板过程的学习笔记&#xff0c;可能有误&#xff0c;详细请看B站野火官方配套视频教程&#xff08;这个教程真的讲的很详细&#xff0c;请给官方三连吧&#xff09; 在响应绿色发展的同时&#xff0c;在很多应用场合中都对电子设备的功…

[JAVA]MyBatis框架—如何获取SqlSession对象实现数据交互(基础篇)

假设我们要查询数据库的用户信息&#xff0c;在MyBatis框架中&#xff0c;首先需要通过SqlSessionFactory创建SqlSession&#xff0c;然后才能使用SqlSession获取对应的Mapper接口&#xff0c;进而执行查询操作 在前一章我们学习了如何创建MyBatis的配置文件mybatis.config.xm…

【视频讲解】Python深度神经网络DNNs-K-Means(K-均值)聚类方法在MNIST等数据可视化对比分析...

全文链接&#xff1a;https://tecdat.cn/?p38289 分析师&#xff1a;Cucu Sun 近年来&#xff0c;由于诸如自动编码器等深度神经网络&#xff08;DNN&#xff09;的高表示能力&#xff0c;深度聚类方法发展迅速。其核心思想是表示学习和聚类可以相互促进&#xff1a;好的表示会…

Java 网络编程(二)—— TCP流套接字编程

TCP 和 UDP 的区别 在传输层&#xff0c;TCP 协议是有连接的&#xff0c;可靠传输&#xff0c;面向字节流&#xff0c;全双工 而UDP 协议是无连接的&#xff0c;不可靠传输&#xff0c;面向数据报&#xff0c;全双工 有连接和无连接的区别是在进行网络通信的时候&#xff0c;…

机器学习—正则化和偏差或方差

正则化参数的选择对偏差和方差的影响 用一个四阶多项式&#xff0c;要用正则化拟合这个模型&#xff0c;这里的lambda的值是正则化参数&#xff0c;它控制着你交易的金额&#xff0c;保持参数w与训练数据拟合&#xff0c;从将lambda设置为非常大的值的示例开始&#xff0c;例如…

【笔记】企业架构TOGAF 10的架构从4A增加至6A

背景 谈谈学习TOGAF 10的总结和笔记&#xff0c;说说较9.2版本有哪些变化。最直观的当属从原来的4A架构升级到6A架构&#xff0c;单独从原来的4A中提炼形成了安全架构、系统架构两个概念&#xff0c;谈谈理解并回顾总结一下学习笔记。 TOGAF 10 将安全架构单独列为一种架构&…

AI写作(十)发展趋势与展望(10/10)

一、AI 写作的崛起之势 在当今科技飞速发展的时代&#xff0c;AI 写作如同一颗耀眼的新星&#xff0c;迅速崛起并在多个领域展现出强大的力量。 随着人工智能技术的不断进步&#xff0c;AI 写作在内容创作领域发挥着越来越重要的作用。据统计&#xff0c;目前已有众多企业开始…

【模块一】kubernetes容器编排进阶实战之资源管理核心概念

kubernetes 资源管理核心概念 k8s的设计理念—分层架构 CRI-container runtime interface-容器运行接口 CNI-container network interface-容器网络接口 CSI-container storage interface-容器存储接口 k8s的设计理念—API设计原则 https://www.kubernetes.org.cn/kubernete…

DBeaver中PostgreSQL数据库显示不全的解决方法

本文介绍在DBeaver中&#xff0c;连接PostgreSQL后&#xff0c;数据库显示不全的解决方法。 最近&#xff0c;在DBeaver中连接了本地的PostgreSQL数据库。但是连接后打开这个数据库时发现&#xff0c;其所显示的Databases不全。如下图所示&#xff0c;Databases只显示了一个pos…

ElasticSearch学习笔记二:使用Java客户端

一、前言 在上一篇文章中&#xff0c;我们对ES有了最基本的认识&#xff0c;本着实用为主的原则&#xff0c;我们先不学很深的东西&#xff0c;今天打算先学习一下ES的Java客户端如何使用。 二、创建项目 1、普通Maven项目 1、创建一个Maven项目 2、Pom文件 <dependenc…

MySQL8 安装教程

一、从官网下载mysql-8.0.18-winx64.zip安装文件&#xff08; 从 https://dev.mysql.com/downloads/file/?id484900 下载zip版本安装包 mysql-8.0.18-winx64.zip 解压到本地磁盘中&#xff0c;例如解压到&#xff1a;D盘根目录&#xff0c;并改名为MySQL mysql-8.0.34-winx6…

如何将LiDAR坐标系下的3D点投影到相机2D图像上

将激光雷达点云投影到相机图像上做数据层的前融合&#xff0c;或者把激光雷达坐标系下标注的物体点云的3d bbox投影到相机图像上画出来&#xff0c;都需要做点云3D点坐标到图像像素坐标的转换计算&#xff0c;也就是LiDAR 3D坐标转像素坐标。 看了网上一些文章都存在有错误或者…