简单了解一下 TypeScript 的泛型

news2024/12/6 1:09:30

在 TypeScript (TS) 中,泛型是一个强大且灵活的工具,用于编写具有更高可复用性和类型安全性的代码。泛型允许我们在声明时将类型作为参数传入,使函数、接口和类能在不同的数据类型下复用,而无需重新编写逻辑。

1. 泛型的基本语法

泛型的基本语法是在函数、接口、类等结构后添加尖括号 <>,并指定一个类型参数(通常用大写字母如 T 表示)。

🌰:

function identity<T>(arg: T): T {
  return arg;
}

这里 T 是泛型类型,它表示一个占位符,可以是任何类型。函数 identity 接受一个参数 arg,其类型是 T,并返回相同类型的 T。当我们调用时,可以指定具体类型,如: identity<string>("Hello")。

2. 泛型在函数中的使用

在函数中,泛型可以用来定义参数返回值的类型,从而提高代码的灵活性和可复用性。

一个经典的 🌰 是数组的泛型方法:

function logArray<T>(arr: T[]): T[] {
  console.log(arr);
  return arr;
}

logArray 接收一个类型为 T 数组的参数,并返回该数组,T 可以是任意类型。通过这种方式,我们可以传入 string[]、number[] 等不同类型的数组,而不需要为每种类型写单独的函数。

3. 泛型在接口中的应用

泛型在接口中使用时,可以使接口支持不同的类型数据。

🌰,在定义一个具有 value 属性和 getValue 方法的接口时,可以使用泛型来灵活指定 value 的类型:

interface Box<T> {
  value: T;
  getValue(): T;
}
const stringBox: Box<string> = {
  value: 'Hello',
  getValue() {
    return this.value;
  },
};
const numberBox: Box<number> = {
  value: 18,
  getValue() {
    return this.value;
  },
};

Box<T> 接口可以适用于任何类型的 value,如 string、number,甚至是自定义类型。

4. 泛型在类中的应用

泛型在类中也有广泛的应用,特别是在需要处理不同类型的集合、数据结构时。

🌰:

class Stack<T> {
  private items: T[] = [];
  push(item: T) {
    this.items.push(item);
  }
  pop(): T | undefined {
    return this.items.pop();
  }
}

Stack 类使用了泛型 T,从而可以创建不同类型的栈,如 Stack<number> 或 Stack<string>。

5. 泛型约束(Constraints)

在某些情况下,我们可能希望限制泛型参数的类型范围,可以通过泛型约束实现这一点。

🌰,使用 extends 关键字来约束泛型类型必须具有某些属性或实现某个接口:

interface LengthType {
  length: number;
}
function logLength<T extends LengthType>(arg: T): T {
  console.log(arg.length);
  return arg;
}

logLength 函数的泛型参数 T 被约束为具有 length 属性的类型,这意味着只能传入具有 length 属性的对象,例如数组或字符串。

6. 多个泛型参数

有时一个泛型类型参数无法满足需求,此时可以使用多个泛型参数。

🌰:

function pair<T, U>(a: T, b: U): [T, U] {
  return [a, b];
}
pair(1, 1);
pair(1, '1');
pair('1', true);

pair 函数中,T 和 U 是两个泛型参数,允许我们将任意类型的两个值组合成一个元组。

7. 泛型的默认类型

TypeScript 支持为泛型提供默认类型,这样在没有指定类型时可以使用默认值:

🌰:

function createArray<T = number>(length: number, value: T): T[] {
  return Array(length).fill(value);
}

const arr = createArray(3, 5); // 推断 T 为 number
const strArr = createArray<string>(3, 'Hello'); // 显式指定 T 为 string

createArray 函数中,设置 T 默认类型 number,这样如果调用时不指定类型,T 将默认为 number。

8. 泛型工具类型(Utility Types)

TypeScript 提供了一些内置的工具类型,可以用于处理泛型类型。例如:

- Partial<T>:将类型 T 中的所有属性变成可选。

- Readonly<T>:将类型 T 中的所有属性变为只读。常用于防止对象被修改的情况。

interface User {
  id: number;
  name: string;
  age: number;
}
type PartialUser = Partial<User>; // { id?: number; name?: string; age?: number; }
const user1: PartialUser = { name: 'Alice' }; // 只需要部分属性
const user2: PartialUser = {}; //也可以一个都不写
const user3: Readonly<User> = { id: 1, name: 'Alice', age: 30 }; // { readonly id: number; readonly name: string; readonly age: number; }
// user3.age = 31; // 错误:因为 user 是只读的
// const user4: Readonly<User>; // 'const' declarations must be initialized. 必须初始化 const 声明。

- Record<K, T>:将键类型为 K 的所有键映射到类型 T 的值。K 必须是字符串或字符串字面量的联合类型。常用于创建对象映射或字典。

type Role = 'admin' | 'user' | 'guest';
type Permission = Record<Role, boolean>; // 表示每个角色是否具有某种权限。

const permissions: Permission = {
  admin: true,
  user: false,
  guest: false,
};

- Pick<T, K>:从类型 T 中选择一些属性构成新的类型。

- Omit<T, K>:从类型 T 中剔除一些属性构成新的类型。

interface User {
  id: number;
  name: string;
  age: number;
}
type UserPreview = Pick<User, 'id' | 'name'>;
const userPreview: UserPreview = { id: 1, name: 'Alice' }; // 只包含 id 和 name

type UserWithoutAge = Omit<User, "age">;
const userWithoutAge: UserWithoutAge = { id: 1, name: "Alice" }; // age 属性被去除

9. 泛型的优势与趋势

1、可复用性:泛型允许编写更通用的代码,减少重复,提高可维护性。

2、类型安全:相比于 any,泛型提供了明确的类型约束,能够在编译时捕获错误,提升代码的可靠性。

3、适用性广:泛型在函数、接口、类、工具类型中均可使用。

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

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

相关文章

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-16

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

Vulnhub靶机——DC-3

#环境准备 dc-3 虚拟机&#xff1a;网卡NAT模式 kali攻击机&#xff1a;网卡NAT模式 #信息收集 nmap轻车熟路扫一下dc3的地址&#xff0c;识别出joomla系统 面向百度渗透&#xff0c;得知有一个joomla的扫描器&#xff0c;直接安排上&#xff0c;这下有版本号和后台登录地址…

数据结构:七种排序及总结

文章目录 排序一插入排序1直接插入排序2希尔排序二选择排序3直接选择排序4堆排序三 交换排序5冒泡排序6快速排序四 归并排序7归并排序源码 排序 我们数据结构常见的排序有四大种&#xff0c;四大种又分为七小种&#xff0c;如图所示 排序&#xff1a;所谓排序&#xff0c;就是…

基于STM32H7XX的Bootloader启动与FOTA

1. Bootloader是如何工作的: 2.正常情况下,程序从flash启动时的启动流程,如下图所示: 首先程序从flash启动,根据中断向量表找到复位中断处理函数的地址(0x0800 0004处是中断向量表的起始地址,记录了复位中断处理函数的地址)。执行复位中断处理函数,初始化系统环境之后…

语音 AI 迎来爆发期,也仍然隐藏着被低估的机会丨RTE2024 音频技术和 Voice AI 专场

在人工智能快速发展的今天&#xff0c;语音交互技术正经历一场革命性的变革。从语音识别到语音合成&#xff0c;再到端到端的语音对话系统&#xff0c;这一领域的创新正以前所未有的速度推进。这些进步不仅提升了技术指标&#xff0c;更为实时翻译、虚拟数字人、智能客服等实时…

【自学笔记】神经网络(1)

文章目录 介绍模型结构层&#xff08;Layer&#xff09;神经元 前向传播反向传播Q1: 为什么要用向量Q2: 不用激活函数会发生什么 介绍 我们已经学习了简单的分类任务和回归任务&#xff0c;也认识了逻辑回归和正则化等技巧&#xff0c;已经可以搭建一个简单的神经网络模型了。 …

在内蒙考驾照需要注意什么呢?

一、报名条件 年满18周岁&#xff0c;具有完全民事行为能力的中国公民。持有有效的身份证明文件。身体健康&#xff0c;无妨碍驾驶机动车的疾病&#xff0c;并需要通过体检。 二、选择驾校 可以先向身边已经拿到驾照的朋友咨询&#xff0c;了解驾校的距离、位置、口碑等信息。…

C++builder中的人工智能(8)什么是神经网络中的恒等激活函数?

在这篇文章中&#xff0c;我们将回答以下问题&#xff1a; 你想了解神经网络中最简单的激活函数是什么吗&#xff1f;什么是恒等函数&#xff1f;作为AI术语&#xff0c;我们需要了解激活函数和转移函数的哪些知识&#xff1f;激活函数与净输入函数是一回事吗&#xff1f;是否…

django图书管理系统-计算机毕业设计源码00648

摘要 图书管理系统在数字化阅读趋势、图书馆自动化管理、用户体验需求和信息技术应用等方面具有重要的研究意义。图书馆自动化管理系统的引入和应用提高了图书借阅过程的效率和准确性&#xff0c;减少了对手工操作和纸质记录的需求。用户对系统的易用性、查询速度、借还流程有更…

文件系统和日志管理

文件系统 文件系统&#xff1a; 文件系统提供了一个接口&#xff0c;用户用来访问硬件设备硬件设备上对文件的管理 存储单位 文件存储在硬盘上&#xff0c;硬盘最小的存储单位是512字节 扇区&#xff0c;文件在硬盘上的最小存储单位&#xff1a;块block&#xff0c;一个块的…

【代码转换】如何用 GPT 将 Python2代码 转换为 Python3代码 :实战教程

文章目录 1. 为什么要将 Python 2 代码迁移到 Python 3&#xff1f;2. 使用 ChatGPT 进行代码转换的步骤步骤1&#xff1a;打开CodeMoss步骤2&#xff1a;在输入框输入符号&#xff0c;选择代码转换步骤3&#xff1a;在这里选择你要更改的具体代码步骤4&#xff1a;准备 Python…

「Mac畅玩鸿蒙与硬件27」UI互动应用篇4 - 猫与灯的互动应用

本篇将带领你实现一个趣味十足的互动应用&#xff0c;用户点击按钮时猫会在一排灯之间移动&#xff0c;猫所在的位置灯会亮起&#xff08;on&#xff09;&#xff0c;其余灯会熄灭&#xff08;off&#xff09;。应用会根据用户的操作动态更新灯光状态和文本提示当前亮灯的位置&…

ES海量数据插入如何优化性能?

2024年10月NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。百度文心快码总经理臧志分享了《AI原生研发新范式的实践与思考》&#xff0c;探讨了大模型赋能下的研发变革及如何在公司和行业中落地&#xff0c;AI原生研发新范式的内涵和推动经验。 …

OTFS基带通信系统(脉冲导频,信道估计,MP解调算法)

Embedded Pilot-Aided Channel Estimation for OTFS in Delay–Doppler Channels | IEEE Journals & Magazine | IEEE Xplore 一、OTFS通信系统 如下图简要概括了OTFS基带通信系统过程&#xff0c;废话不多说给出完整系统详细代码。 以下仿真结果基于四抽头信道 估计信道…

理解Web登录机制:会话管理与跟踪技术解析(二)-JWT令牌

JWT令牌是一种用于安全地在各方之间传递信息的开放标准&#xff0c;它不仅能够验证用户的身份&#xff0c;还可以安全地传递有用的信息。由于其结构简单且基于JSON&#xff0c;JWT可以在不同的系统、平台和语言间无缝传递&#xff0c;成为现代Web开发中不可或缺的一部分。 文章…

微积分复习笔记 Calculus Volume 1 - 4.8 L’Hôpital’s Rule

4.8 L’Hpital’s Rule - Calculus Volume 1 | OpenStax

用户流定义:绘制产品交互流程图

产品经理在进行产品设计时&#xff0c;经常利用交互流程图来提升团队的工作效率。这种流程图适用于传达方案、评审目标等需要团队协作的场景&#xff0c;使得视觉设计师、产品开发等团队成员能够迅速理解图示内容&#xff0c;节省了理解时间&#xff0c;有效提高了沟通效率。 …

Linux -- 冯诺依曼体系结构(硬件)

目录 概念 五大组成部分 为什么需要存储器&#xff1f; 计算机存储金字塔层状结构 为什么程序需要加载到内存中 概念 冯诺依曼体系结构是以数学家冯诺依曼的名字命名的一种计算机体系结构。这种体系结构是现代计算机的基础&#xff0c;它定义了计算机的基本组件及其相互…

群控系统服务端开发模式-应用开发-本地上传工厂及阿里云上传工厂开发

记住业务流程图&#xff0c;要不然不清楚自己封装的是什么东西。 一、本地工厂开发 在根目录下extend文件夹下Upload文件夹下channel文件夹中&#xff0c;我们修改LocalUpload业务控制器。具体代码如下&#xff1a; <?php /*** 本地上传工厂* User: 龙哥 三年风水* Date: …

鹧鸪云光伏小程序上线啦

为了适应市场的发展需求&#xff0c;现推出了手机端SaaS版的光伏小程序&#xff0c;里面包含很多免费的小工具&#xff0c;供给我们业务人员、施工人员方便手机上操作&#xff0c;省去了带着电脑的笨重。下面给大家介绍下里面的免费小工具。 功率的换算&#xff1a;这里主要计…