全面解析 TypeScript 泛型的二三事

2024年了相信大家都已经在日常开发的过程中使用上了 TypeScript 了。TypeScript 增强了代码可靠性和可维护性,确保减少运行时错误并提高开发人员的工作效率。

TypeScript 通过类型声明 使得 javascript 拥有了强类型校验。而泛型的是类型声明中最重要的一环,通过运用 泛型, 可以让我们更好地扩展类型声明。

今天我们来分析一下 TypeScript 泛型。

什么是泛型

我们先来看一下真实的仓库里面写的一个泛型带来的压迫感吧(hhhh)

第一眼看上去感觉东西很多,,,不知道从哪里看过来

说回来,泛型简单来说(Generics)是一种可以使类、接口和函数能够处理不同类型的方式,而不需要明确指定具体的类型。

TypeScript 中,泛型通过在类、接口和函数的声明中引入类型变量来实现。

这里我们可以看一个函数定义泛型的示例:

红色的方框:定义的泛型类型 SomeType

黄色的方框:使用泛型SomeType来约束函数的参数是 SomeType类型数组

绿色的方框:约束函数的返回值为 泛型 SomeType 本身

需要注意的是,泛型本身不是 TypeScript 类型,而是类型参数,即调用函数时将指定的类型的占位符。

对于泛型的命名,可以将其命名为任何您想要的名称(只要它不是保留关键字(例如 constenum)或已导入的类型名称)。一般我们经常使用单个字母来表示泛型,例如 T

其实可以简单理解为 泛型 是一种 类型的占位

定义泛型

函数参数的泛型定义

在函数中使用泛型,常用于约束函数参数的类型。需要注意的是函数参数的泛型定义和调用都是定义在函数参数列表的括号前

我们还可以定义多个泛型,只要通过 , 进行分隔就行

接口 Interface 的泛型定义

接口的泛型定义的位置是紧跟在接口名称后面

当泛型在使用的时候,指定了具体的类型之后,我们就不能违背这个类型,否则会触发 TypeScript 编译错误的提示

类型别名 type 的泛型定义

同样的类型别名也可以通过定义泛型来扩大自己的类型声明范围。类型别名定义泛型的位置和接口 Interface 定义的方式是一致的

Class 的泛型定义

类定义泛型是在 类名 后面,如果是匿名类的话,就是直接定义在 class 后面。

泛型的约束

泛型通过 extend 关键字实现泛型的约束,就是在一些场景下,你知道这个泛型的类型不确定,但是你知道这个类型一定有一些固定的属性,或者一定是属于某一个基础类型,这时候我们可以使用泛型约束,确保传递的参数一定具有某个属性或者属于某一种类型,这样就能安全地在 函数体内执行相关的属性或方法

如果我们传递的类型不满足约束条件时, TS 就会在运行的阶段会提示我们,这样可以避免我们产生后续的 bug

泛型的默认类型

泛型的默认类型和参数的默认类型一样,也是通过 = 来声明一个泛型的默认类型

使用默认类型,可以让我们在调用的时候,如果不传递类型给泛型,泛型也能获取到默认类型应用到具体的变量约束上。

infer 在泛型中的应用

在泛型中,我们经常会使用 infer 对泛型做进一步的类型推定, 进一步将范围进行缩小,推断到我们想要的类型。

这里我们可以看一下 内置的 ReturnType 的实现

在这个示例中,ReturnType 是一个条件类型,它检查类型 T 是否符合函数类型 (...args: any[]) => infer R。如果 T 是一个函数类型,TypeScript 会推断出函数的返回类型 R

infer 目前只能在 extends 的条件语句中

内置的泛型工具函数

TS 内置了很多工具函数,具体可以查看官方文档关于Utility Types 部分

Partial

将类型 T 的所有属性变为可选属性。

  • keyof T 获取类型 T 的所有属性名。
  • [P in keyof T] 是一个映射类型,它遍历 T 的所有属性名。
  • T[P] 获取属性名 P 对应的属性类型。
  • ?: 将属性变为可选属性。

Required

将类型 T 的所有属性变为必选属性。

  • keyof T 获取类型 T 的所有属性名。
  • [P in keyof T] 是一个映射类型,它遍历 T 的所有属性名。
  • T[P] 获取属性名 P 对应的属性类型。
  • -? 移除可选属性修饰符 ?,将属性变为必选属性。

Readonly

将类型 T 的所有属性变为只读属性。

  • keyof T 获取类型 T 的所有属性名。
  • [P in keyof T] 是一个映射类型,它遍历 T 的所有属性名。
  • T[P] 获取属性名 P 对应的属性类型。
  • readonly 将属性变为只读属性。

小结

泛型作为 ts 中重要的基石的存在,学会了 泛型的使用,可以让我们编写更加健壮且可维护的代码

如果这篇文章对你有帮助,欢迎点赞、关注、转发!

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

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

相关文章

Nettyの源码分析

本篇为Netty系列的最后一篇,按照惯例会简单介绍一些Netty相关核心源码。 1、Netty启动源码分析 代码就使用最初的Netty服务器案例,在bind这一行打上断点,观察启动的全过程: 由于某些方法的调用链过深,节约篇幅&#xf…

Linux内核链表使用方法

简介: 链表是linux内核中最简单,同时也是应用最广泛的数据结构。内核中定义的是双向链表。 linux的链表不是将用户数据保存在链表节点中,而是将链表节点保存在用户数据中。linux的链表节点只有2个指针(pre和next),这样的话&#x…

在Linux操作系统使用逻辑卷的快照(snapshot),进行对逻辑卷的数据备份。

作用:结合特定应用程序,方便备份数据。 基于cow(copy on write 写时复制)机制 在创建逻辑卷快照的时候,如果不去设置逻辑卷快照的权限的话,那么这个逻辑卷的权限就是可读可写, 创建逻辑卷快照…

coco数据集格式计算mAP的python脚本

目录 背景说明COCOeval 计算mAPtxt文件转换为coco json 格式自定义数据集标注 背景说明 在完成YOLOv5模型移植,运行在板端后,通常需要衡量板端运行的mAP。 一般需要两个步骤 步骤一:在板端批量运行得到目标检测结果,可保存为yol…

AI教你如何系统的学习Python

Python学习计划 第一阶段:Python基础(1-2个月) 目标:掌握Python的基本语法、数据类型、控制结构、函数、模块和包等。 学习Python基本语法:包括变量、数据类型(整数、浮点数、字符串、列表、元组、字典、…

STM32基础篇:GPIO

GPIO简介 GPIO:即General Purpose Input/Output,通用目的输入/输出。就是一种片上外设(内部模块)。 对于STM32的芯片来说,周围有一圈引脚,有时需要对引脚进行读写(读:从外部输入一…

【xinference】(15):在compshare上,使用docker-compose运行xinference和chatgpt-web项目,配置成功!!!

视频演示 【xinference】(15):在compshare上,使用docker-compose运行xinference和chatgpt-web项目,配置成功!!! 1,安装docker方法: #!/bin/shdistribution$(…

【嵌入式DIY实例-ESP8266篇】-LCD ST7735显示BMP280传感器数据

LCD ST7735显示BMP280传感器数据 文章目录 LCD ST7735显示BMP280传感器数据1、硬件准备与接线2、代码实现本文介绍如何将 ESP8266 NodeMCU 板 (ESP-12E) 与 Bosch Sensortec 的 BMP280 气压和温度传感器连接。 NodeMCU 微控制器 (ESP8266EX) 从 BMP280 传感器读取温度和压力值,…

VUE3初学入门-02-VUE创建项目

创建VUE项目的另一个方法 三种方法通过vue-cli进行创建通过npm进行创建比较 部署到nginx修改配置生成部署文件 三种方法 上一篇是在VSCODE中建立工作区,然后创建,属于命令加鼠标方式。个人感觉,在VSCODE基本上都是这样的操作,不是…

vue3中svg图标的封装与使用

组件封装&#xff1a; <template><svg :class"svgClass" :style"{ width: size px, height: size px, color: color, verticalAlign:deviationem}" aria-hidden"true"><use :xlink:href"#icon-${name}" /></s…

Python编程学习笔记(2)--- 列表简介

1、列表是什么 列表由一系列按特定顺序排列的元素组成。可以创建包含字母表中所有字母、数字、0~9或所有家庭成员姓名的列表&#xff1b;也可以将任何东西加入列表中&#xff0c;其中的元素之间可以没有任何关系。列表通常包含多个元素&#xff0c;因此给列表指定一个表示复数…

基于SSM+JSP的KTV点歌系统(带1w+文档)

基于SSMJSP的KTV点歌系统(带1w文档) 开发一个KTV点歌系统可以解决不利于线下点歌的问题&#xff0c;同时管理员可以利用网络对KTV点歌系统信息进行管理&#xff0c;设计的网站保证信息的完整安全&#xff0c;这样才能提高工作效率&#xff0c;保证系统安全正常的运行。 项目简介…

vim未找到命令,且yum install vim安装vim失败

vim未找到命令&#xff0c;且yum安装vim失败 1、wget更新yum云资源&#xff0c;本次更新为华为云镜像资源 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.huaweicloud.com/repository/conf/CentOS-7-anon.repowget报未找到命令&#xff0c;请查看文章Linux wget…

iOS UITableView自带滑动手势和父视图添加滑动手势冲突响应机制探索

场景 我们有时候会遇到这样的一个交互场景&#xff1a;我们有一个UITableView 放在一个弹窗中&#xff0c;这个弹窗可以通过滑动进行展示和消失&#xff08;跟手滑动的方式&#xff09;&#xff0c;然后这个UITableView放在弹窗中&#xff0c;并且可以滚动&#xff0c;展示一些…

昇思25天学习打卡营第19天|Diffusion扩散模型

学AI还能赢奖品&#xff1f;每天30分钟&#xff0c;25天打通AI任督二脉 (qq.com) Diffusion扩散模型 本文基于Hugging Face&#xff1a;The Annotated Diffusion Model一文翻译迁移而来&#xff0c;同时参考了由浅入深了解Diffusion Model一文。 本教程在Jupyter Notebook上成…

Python数据分析案例50——基于EEMD-LSTM的石油价格预测

案例背景 很久没更新时间序列预测有关的东西了。 之前写了很多CNN-LSTM&#xff0c;GRU-attention&#xff0c;这种神经网络之内的不同模型的缝合&#xff0c;现在写一个模态分解算法和神经网络的缝合。 虽然eemd-lstm已经在学术界被做烂了&#xff0c;但是还是很多新手小白或…

RAG 案框架(Qanything、RAGFlow、FastGPT、智谱RAG)对比

各家的技术方案 有道的QAnything 亮点在&#xff1a;rerank RAGFLow 亮点在&#xff1a;数据处理index 智谱AI 亮点在文档解析、切片、query改写及recall模型的微调 FastGPT 优点&#xff1a;灵活性更高 下面分别按照模块比较各框架的却别 功能模块QAnythingRAGFLowFastG…

MPC学习资料汇总

模型预测控制MPC学习资料汇总 需要的私信我~ 需要的私信我~ 需要的私信我~ 【01】课件内容 包含本号所有MPC课程的课件&#xff0c;以及相关MATLAB文档。 【02】课件源代码 本号所有MPC课程的源代码。 【03】MPC仿真案例 三个MPC大型仿真案例&#xff1a; 1&#xff09;…

力扣爆刷第160天之TOP100五连刷66-70(回溯、旋转图像、技巧题)

力扣爆刷第160天之TOP100五连刷66-70&#xff08;回溯、旋转图像、技巧题&#xff09; 文章目录 力扣爆刷第160天之TOP100五连刷66-70&#xff08;回溯、旋转图像、技巧题&#xff09;一、110. 平衡二叉树二、39. 组合总和三、543. 二叉树的直径四、470. 用 Rand7() 实现 Rand1…

win系统提示VCRUNTIME140_1.dll丢失或找不到的8个处理方法

在使用电脑过程中经常会遇到各种各样的问题&#xff0c;比如vcruntime140_1.dll丢失或找不到vcruntime140_1.dll无法继续执行代码就是其中的一个常见问题!那么遇到vcruntime140_1.dll丢失问题要怎么处理&#xff1f;vcruntime140_1.dll是什么&#xff1f;下面我给大家详细介绍v…