【TypeScript】TS泛型讲解及其使用

news2024/12/25 8:59:53

目录

泛型

泛型函数使用

泛型约束

多泛型使用

泛型接口

泛型类

泛型工具类型


泛型

泛型是可以在保证类型安全的前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class中。日常我们创建的函数,传入什么数据就返回什么数据本身,即参数与返回值的类型相同,如下:

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

而为了能够让函数接收任何类型,我们以前可以将参数类型修改为any。但这样就失去了TS的类型保护,类型不安全,泛型在保证类型安全的同时(不丢失类型信息),可以让函数与多种不同的类型一起工作,灵活可复用。

泛型函数使用

创建泛型函数:我们在创建函数的同时在函数名称后面添加 <> (尖括号),尖括号中添加类型变量,如下:

当然创建泛型函数的类型变量可以是任意合法变量名称,不仅仅是下面例子中的type。

// 类型变量 type 是一种特殊类型的变量,它只处理类型不处理值。
// 该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体类型由用户调用函数时指定)
function add<type>(value: type): type{
  return value
}

调用泛型函数

在调用函数的同时在函数后面声明自己要传入参数的类型,用 <> 进行包裹。

// 创建泛型函数
function add<type>(value: type): type{
  return value
}
// 调用泛型函数
const num = add<number>(10) // 以 number 类型调用函数
const str = add<string>('s') // 以 string 类型调用函数
const ret = add<boolean>(true) // 以 boolean 类型调用函数

当然在调用泛型函数时,可以省略<类型>来简化泛型函数的调用。因为TS内部会采用一种叫做类型参数推断的机制,来根据传入的参数自动推断出类型变量的类型。使用这种简化的方式调用泛型函数,使代码更短更便于阅读。

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

泛型约束

默认情况下,泛型函数的类型变量可以代表多个类型,这就导致无法访问任何属性。比如当我们需要获取字符串长度时使用泛型就会报错,因为泛型代表任意类型无法保证一定存在某个属性,此时就需要为泛型 添加约束 缩窄类型取值范围

添加泛型约束收缩类型主要有以下两种方式:

指定更具体的类型:可以根据自身需要将泛型函数的类型修改来获取属性,如下:

// 创建泛型函数
function add<type>(value: type[]): type{
  console.log(value.length)
  return value
}

添加约束:可以创建描述约束的接口来提供自己的属性,通过 extends 关键字为类型变量添加约束

interface MyLength {length:number}
// 创建泛型函数
function add<type extends MyLength>(value: type): type{
  console.log(value.length)
  return value
}
add([1,2])
add('123')
add({name:'张三',length:12,age:13})

多泛型使用

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

// 创建泛型函数
// keyof关键字接收一个对象类型,生成其键名称(或字符串或者数字)的联合类型
function add<type,key extends keyof type>(obj: type,value: key) {
  return obj[value]
}
add(18,"toString")
add({name:'张三',age:18},"name")

泛型接口

接口的名称后面添加 <类型变量> ,那么这个接口就变成了泛型接口。接口也可以搭配泛型来使用,以增加其灵活性,增强其复用性。

interface person<type> {
  id: (value:type) => type
  ids: ()=> type[]
}
// 使用泛型接口时一定要显式指定具体类型,否则报错
let p: person<number> ={
  id(value){
    return value
  },
  ids() {
    return [1,2,3]
  },
}

泛型类

class也可以配合泛型来使用。

创建泛型类

类似于泛型接口,在class名称后面添加<类型变量>,这个类就变成了泛型类。

class Animals<type> {
  defaultValue: type
  say: (x: number,y :number) => type
  constructor(value: type){
    this.defaultValue = value
  }
}
// 当我们提供 constructor 并且里面已经提供类型了,这个时候我们new实例的时候,类型可以省略。
// const num = new Animals<number>(10)
const num = new Animals(10)

泛型工具类型

TS内置了一些常用的工具类型,来简化TS中的一些常见操作。它们都是基于泛型实现的,并且都是内置的,可以直接在代码中使用。这些工具类很多,主要学习以下几个:

Partial<type>:用来构造一个类型,将type的所有属性设置为可选。

interface People {
  name: string
  age: number
  hobby: number[]
}
// 使的接口属性变为可选属性
type commenPeople = Partial<People>
// 调用接口,属性一定必须
let p1: People = {
  name:'张三',
  age:18,
  hobby:[1,2]
}
// 使用 Partial 使的接口属性变为可选
let p2: commenPeople = {
  name:''
}

Readonly<type>:用来构造一个类型,将type的所有属性都设置为 readonly (只读)。

interface People {
  name: string
  age: number
  hobby: number[]
}
// 使的接口属性变为可选属性
type ReadonlyPeople = Readonly<People>
// 调用接口,属性一定必须
let p1: ReadonlyPeople = {
  name:'张三',
  age:18,
  hobby:[1,2]
}
// 无法分配到 "name" ,因为它是只读属性。
// p1.name = '李四' 

Pick<type,keys>:从type中选择一组属性来构造新类型。 Pick工具类型有两个类型变量:第一个表示选择谁的属性;第二个表示选择哪几个属性。注意:第二个类型变量传入的属性只能是第一个类型变量中存在的属性。

interface People {
  name: string
  age: number
  hobby: number[]
}
// 使的接口属性变为可选择属性
type RickPeople = Pick<People,'name'|'hobby'>
// 调用接口,属性一定必须
let p1: RickPeople = {
  name:'张三',
  // 对象文字可以只指定已知属性,并且“age”不在类型“RickPeople”中。
  // age:18,
  hobby:[1,2]
}

Record<keys,type>:构造一个对象类型,属性键位keys,属性值为type。

type RecordObj = Record<'a'|'b'|'c',string[]>
let obj: RecordObj = {
  a:['1'],
  b:['1'],
  c:['1']
}

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

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

相关文章

车牌检测模型训练(含源码和数据集)

车牌检测模型训练(含源码和数据集) 本教程利用NVIDIA TAO进行车牌检测模型的训练: 模型框架:SSD数据集: CRPD, 连接:https://github.com/yxgong0/CRPD训练框架: NVIDIA TAO, 安装教程连接: https://docs.nvidia.com/tao/tao-toolkit/text/tao_toolkit_quick_start_guide.html…

目标检测之YOLOv3算法分析

基本原理 特征网络 输入输出 输入416∗416∗3416*416*3416∗416∗3大小的图片&#xff08;不唯一&#xff0c;但图片大小必为32的倍数&#xff09;&#xff0c;输出3个尺度的feature map,分别为13∗13∗25513*13*25513∗13∗255&#xff0c;26∗26∗25526*26*25526∗26∗255…

RV1126笔记十九:吸烟行为检测及部署<六>

若该文为原创文章,转载请注明原文出处。 模型测试 一、pt文件测试 pt文件是在windows下训练生成的,测试环境为py3.8 1、首先查看虚拟环境列表,然后切换于是py3.8的虚拟环境。 conda env list // 查看虚拟环境列表 conda activate yolo // 切换虚拟环境 2…

leetcode:1739. 放置盒子【找规律!】

目录题目截图题目分析ac code总结题目截图 题目分析 样例有规律&#xff0c;它希望我们先按每层1, 3, 6这样叠起来&#xff0c;比如能跌i层那么至少有i * ( i 1) // 2个底层多出来的东西再做考虑多出来的东西考虑1 2 3…能加到多少个比如说如果多出来3个的话&#xff0c;放…

【小5聊】Asp.Net Core3.1基础之跨域设置以及设置不对的地方

最近微软的.Net Core平台更新换代速度非常快&#xff0c;还没把2.1整熟悉&#xff0c;就把2.1淘汰了。 目前最新版本已经到了7.0&#xff0c;.net core3.1还在长期维护范围内&#xff0c;估计能用一段时间。 所以&#xff0c;.net core2.1升级到3.1&#xff0c;跨域方法的设置也…

gerber 文件格式 [一]

在电路设计这块, 目前还绕不开 gerber 文件的工程交互, 所以来了解一下. 目前官网的文档gerber-layer-format-specification-revision-2022-02_en.pdf. gerber 文件是一个ascii码的命令文档, 格式比较简单,主要命令有下面这些 命令名称说明G04注释对文档生成没有影响MO模式设…

基于天鹰算法改进的DELM预测-附代码

天鹰算法改进的深度极限学习机DELM的回归预测 文章目录天鹰算法改进的深度极限学习机DELM的回归预测1.ELM原理2.深度极限学习机&#xff08;DELM&#xff09;原理3.天鹰算法4.天鹰算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1a;https:…

一文弄懂 React HOC

1. 提出问题 1.HOC 能解决什么问题&#xff1f; 2.HOC 的使用场景&#xff1f; 2. HOC 能解决什么问题&#xff1f; 1.拦截组件渲染&#xff0c;包括是否渲染组件、懒加载组件 2.往组件的 props 中混入所需的东西&#xff0c;比如给非 Route 组件的 props 混入 history 对象…

node.js+uni计算机毕设项目交流微信小程序LW(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

信号量和共享内存

信号量 信号量(Semaphore)&#xff0c;有时被称为信号灯&#xff0c;是在多线程环境下使用的一种设施&#xff0c;是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前&#xff0c;线程必须获取一个信号量;一旦该关键代码段完成了&#xff0c;那么该线…

Joplin插件推荐-持续更新

背景 之前因为印象笔记、语雀等笔记软件使用起来都不满足自己的需求&#xff0c;所以后面自己调研后使用了Joplin这个开源笔记软件 &#xff0c;项目主页&#xff1a; https://joplinapp.org 。目前搭建在自己的服务器上。最近发现有很多好用的插件。所以记录分享一下。 总插…

# LowCode 低代码建表工具

LowCode 低代码建表工具 需求描述 将数据库的表映射为实体类&#xff0c;服务启动时&#xff0c;扫描表相关的实体类&#xff0c;根据实体类模型在数据库创建相关的表 依赖 主要依赖&#xff1a;使用 Sprintboot、druid、spring-jdbc、mybatis <!-- https://mvnreposit…

为啥这些开源的网络框架这么强

hi&#xff0c; 大家好&#xff0c;我是大师兄&#xff0c;今天分享一下网络编程下半部分内容&#xff0c;主要分享开源网络io框架用到了哪些核心技术&#xff0c;使他们如此流行&#xff0c;这些技术值得我们学习&#xff0c;可以增加我们编程技巧和优化思路。只有掌握更多技能…

【类和对象(上)】

Quitters never win and winners never quit. 目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1 访问限定符 4.2 封装 5.类的作用域 6.类的实例化 7.类对象模型 7.1 如何计算类对象的大小 7.2 结构体内存对齐规则 8.this指针 …

理解 Proxy 和 Reflect

03_02_理解 Proxy 和 Reflect 一、开始之前: 为什么还会有这一篇文章呢&#xff1f;不是手写mini-vue吗&#xff1f;其实可以理解成支线任务、番外篇&#xff0c;是对主线内容的补充。 这一篇文章可能文字比较多&#xff0c;理论知识比较多&#xff0c;参考了4本书相关的章节…

九、Express 基本使用(简)

前一篇内容讲到Express框架的安装以及对Express项目的目录文件有一定的认识了解之后&#xff0c;使用Express创建了最基本的一个Web服务器&#xff0c;接下来进行对Express框架的一些内容来做一个基本的使用&#xff1b; 创建 Web 服务器 node 或 nodemon 执行app.js文件&#…

踩坑了、踩到一个特别无语的常识坑

大家好 踩坑了啊&#xff0c;又踩坑了啊&#xff01; 这次踩到一个特别无语的常识坑。知道真相的那一刻&#xff0c;人就是整个麻掉。 先上个代码&#xff1a; private static double calculate(double a, int b) {return a / b; } 复制代码 你先别问为什么计算不用 BigDec…

RxJS初认识

概念&#xff1a; RxJS的运行就是Observable和Observer之间的互动游戏。 Observable就是“可以被观察的对象”&#xff0c;即“可被观察者”&#xff0c;而Observer就是‘观察者’&#xff0c;连接两者的桥梁就是Observable对象的函数subscribe。 RxJS中的数据流就是Observable…

第二十三章 数论——质数(1)(超级详细的推导)

第二十三章 数论——质数一、什么是质数二、质数的判断1、试除法&#xff08;朴素版&#xff09;2、试除法&#xff08;优化版&#xff09;三、分解质因数1、什么是质因数2、算术基本定理3、分解质因数&#xff08;1&#xff09;问题&#xff08;2&#xff09;思路&#xff08;…

RepNAS: 基于NAS的结构重参数化技术

1. 介绍 在过去几年里&#xff0c;NAS技术取得了长足进展。然而&#xff0c;由于搜索约束与实际推理之间的差异导致高效网络搜索仍极具挑战性。为搜索一个具有高性能、低推理延迟的模型&#xff0c;已有方案往往在算法中添加计算复杂度约束。然而&#xff0c;推理速度会受多种…