【TypeScript】枚举类型和泛型的详细介绍

news2024/11/25 13:01:32

目录

TypeScript枚举类型

TypeScript泛型介绍

🎲泛型的基本使用

🎲泛型接口的使用

🎲泛型类的使用

🎲泛型的类型约束



枚举类型

枚举类型是为数不多的TypeScript特有的特性之一, JavaScript是没有的

枚举其实就是将一组可能出现的值,一个个列举出来,定义在一个类型中,这个类型就是枚举类型;

枚举允许开发者定义一组命名常量,常量可以是数字、字符串类型;

枚举类型使用enum关键字定义, 建议枚举中定义的值使用大写

枚举我们常见的使用方式如下

enum Direction {
  LEFT,
  RIGHT,
  TOP,
  BOTTOM
}

function turnDirection(direction: Direction) {
  switch (direction) {
    case Direction.LEFT:
      console.log("转向左边")
      break;
    case Direction.RIGHT:
      console.log("转向右边")
      break;
    case Direction.TOP:
      console.log("转向上边")
      break;
    case Direction.BOTTOM:
      console.log("转向下边")
      break;
    default:
      const foo: never = direction
      break;
  }
}

// 测试
turnDirection(Direction.LEFT)
turnDirection(Direction.RIGHT)
turnDirection(Direction.TOP)
turnDirection(Direction.BOTTOM)

枚举类型默认是有值的,比如上面代码的枚举,默认值其实是这样的

enum Direction {
  LEFT = 0,
  RIGHT = 1,
  TOP = 2,
  BOTTOM = 3
}

当然,我们也可以给枚举其他值, 比如我们给LEFT一个值: 100

enum Direction {
  LEFT = 100,
  RIGHT,
  TOP,
  BOTTOM
}

这个时候LEFT后面的值如果没有设置值的话, 它们的默认值会从100进行递增, 相当于下面这样:

enum Direction {
  LEFT = 100,
  RIGHT = 101,
  TOP = 102,
  BOTTOM =103
}

我们也可以给他们赋值其他的类型

enum Direction {
  LEFT,
  RIGHT,
  TOP = "TOP",
  BOTTOM = "BOTTOM"
}

TypeScript泛型介绍

🎲泛型的基本使用

软件工程的主要目的是构建不仅仅明确和一致的API,还要让你的代码具有很强的可重用性

比如我们可以通过函数来封装一些API,通过传入不同的函数参数,让函数帮助我们完成不同的操作;

但是对于参数的类型是否也可以参数化呢?

什么是类型的参数化?

我们来提一个需求:封装一个函数,传入一个参数,并且返回这个参数;

如果我们是TypeScript的思维方式,要考虑这个参数和返回值的类型需要一致

// 传入number类型, 返回number类型
function foo(arg: number): number {
  return arg
}

上面的代码虽然实现了,但是不适用于其他类型,比如string、 boolean、 Person等其他类型

为了适用于其他类型, 我们可以定义为any类型

// 传入number类型, 返回number类型
function foo(arg: any): any {
  return arg
}

虽然any是可以的,但是定义为any的时候,我们其实已经丢失了类型信息

比如我们传入的是一个number,那么返回的也是是any类型, 我们并不是希望它返回number类型,我们希望返回number类型;

我们想要做到在函数中可以捕获到参数的类型是number,并且同时使用它来作为返回值的类型;

我们需要在这里使用一种特性的变量 - 类型变量( type variable),它作用于类型,而不是值

我们可以将它看做额外的一个参数;

它可以做到, 在定义这个函数时, 不决定这些参数的类型, 而是让调用者以参数的形式告知, 这里的函数参数应该是什么类型

function foo<Type>(arg: Type): Type {
  return arg
}

这里我们可以使用两种方式来调用它

  • 方式一:通过 <类型> 的方式将类型传递给函数;
foo<number>(123) // 传入number类型
foo<{name: string}>({ name: "chenyq" }) // 传入有name属性的对象类型
foo<number[]>([10, 20]) // 传入number类型的数组
  • 方式二:通过类型推导,自动推导出我们传入变量的类型:

在这里会推导出它们是字面量类型的,因为字面量类型对于我们这个函数也是适用的

foo(50)
foo("aaa")
foo({ name: "kaisa" })

当然我们也可以传入多个类型

function foo<T, E>(arg1: T, arg2: E) {
  console.log(arg1, arg2)
}

foo<number, string>(123, "abc")

平时在开发中我们可能会看到一些常用的名称

T: Type的缩写,类型

K、 V: key和value的缩写,键值对

E: Element的缩写,元素

O: Object的缩写,对象

🎲泛型接口的使用

在定义接口的时候我们也可以使用泛型

// 定义泛型接口
interface IPerson<T1, T2> {
  name: T1
  age: T2
}

const p: IPerson<string, number> = {
  name: "chenyq",
  age: 18
}

泛型接口是没有类型推导的, 但是可以有默认值类型的

// 泛型接口定义默认类型
interface IPerson<T1 = string, T2 = number> {
  name: T1
  age: T2
}

const p: IPerson = {
  name: "chenyq",
  age: 123
}

🎲泛型类的使用

我们也可以编写一个泛型类

class Point<T> {
  x: T
  y: T
  z: T

  constructor(x: T, y: T, z: T) {
    this.x = x
    this.y = y
    this.z = z
  }
}

// 泛型类是可以自动推导类型的
const p1 = new Point("1.22", "3.56", "7.32")
// 也可以自己指定类型, 有下面两种方式
const p2 = new Point<number>(10, 20, 30)
const p3: Point<string> = new Point("1.22", "3.56", "7.32")

🎲泛型的类型约束

有时候我们希望传入的类型有某些共性,但是这些共性可能不是在同一种类型中

比如string和array都是有length的,或者某些对象也是会有length属性的, 但是此时使用泛型, 编译阶段是会报错的, 因为不能保证泛型的所有类型都是有length属性的;

那么只要是拥有length的属性都可以作为我们的参数类型,而没有length属性的不允许作为参数, 那么应该如何操作呢?

我们可以使用接口定义一个对象类型, 对象类型要求必须有length属性, 在让泛型继承自这个接口

interface ILength {
  length: number
}

// 泛型继承自接口
function getLength<T extends ILength>(arg: T) {
  console.log(arg.length)
}

// 测试
// getLength(123) // 123没有length无法传入
getLength("abc") // 3
getLength([10, 20, 30]) // 3
getLength({ length: 10 }) // 10

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

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

相关文章

CiteScore 2022正式发布,AI Open首获即达22.5分,三大高被引论文值得一看

当前&#xff0c;由 ChatGPT、Stable Diffusion 等 AI 大模型掀起的新一轮科技浪潮&#xff0c;正在引领各个行业的变革性发展。及时、深入、全面地了解 AI 行业的前沿动态&#xff0c;有助于我们跟上 AI 行业的发展步伐&#xff0c;抓住时代机遇。 一本学术期刊的高影响力&am…

Java避免踩坑:Set对象排重注意避免重复-以commons-csv读取csv文件并排查为例

场景 HashSet HashSet 基于 HashMap 来实现的&#xff0c;是一个不允许有重复元素的集合。HashSet 允许有 null 值。 HashSet 是无序的&#xff0c;即不会记录插入的顺序。 HashSet 不是线程安全的&#xff0c; 如果多个线程尝试同时修改 HashSet&#xff0c; 则最终结果是…

Classification-based framework for binarization on OCT-ME论文学习和总结

论文&#xff1a;Classification-based framework for binarization on mice eye image in vivo with optical coherence tomography 源码&#xff1a;https://github.com/MIP2019/mip2019.github.io/blob/main/spsvm 目录 一、背景和出发点 二、创新点 三、SPSVM的具体实现…

hive创建udf函数流程

1.编写udf函数 引入pom文件 <dependencies> <dependency> <!-- 这个属于额外的jar包 自己按需引用 比如你想搞得函数 里面要连接mysql 这里肯定需要引入mysql的驱动包 我这个包是为了计算字符串的表达式的。 --> <groupId>org.apache.com…

Git GitLab 使用及规范

Git 基本操作 Git安装配置及基本使用 从官网下载安装包&#xff0c;手动完成安装。打开Git Bash命令行工具&#xff0c;执行命令ssh-keygen -t rsa -C Email-Addresss生成一个密钥对。登录到GitLab&#xff0c;点击右上角你的用户头像&#xff0c;点击Edit Profile settings&…

【Linux】linux和Linus

1991.09.17 21岁的芬兰学生林纳斯.托瓦兹在网上发布开源操作系统Linux0.01。 林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff0c;1969年12月28日- &#xff09;&#xff0c;芬兰赫尔辛基人&#xff0c;著名的电脑程序员&#xff0c;Linux内核的发明人及 …

Revit如何在体量中进行放样及如何生成垫层

一、Revit如何在体量中进行放样 体量中的放样在常规族放样的基础上进行了简化&#xff0c;下面通过实例来说明如何在体量中进行放样。 &#xff08;1&#xff09;新建概念体量。点击“新建概念体量”→“公制体量”→“打开”。 &#xff08;2&#xff09;绘制放样路径。点击“…

盖雅「劳动力账户」助力物业行业实现精细化工时成本管理

物业行业的用工形式和工时制度多样&#xff0c;需要大量的劳动力提供安保、清洁、维修及其他服务&#xff0c;所以人工成本成为了物业公司最大的经营成本之一。而这些员工近半数都是外包人员。因此&#xff0c;物业公司需要利用数字化工具实时记录员工的出勤和工时&#xff0c;…

Grid++Report多个子报表实现

子报表实现参考 GridReport子报表实现 基于上述单个子报表的实现&#xff0c;我们可以衍生多个子报表实现 子报表与主报表可以是关联关系&#xff0c;也可以是独立存在。 配置主从关系字段即代表有关联关系 只有明细网格节点内配置的子报表才可以设置主从关系字段 报表头、…

强光LED手电筒方案开发设计

在户外活动中&#xff0c;不管是徒步还是露营&#xff0c;经常需要使用多功能强光手电筒。宇凡微推出的多功能战术强光LED手电筒方案&#xff0c;具有十多年LED灯项目研发经验&#xff0c;方案成熟&#xff0c;支持定制开发。 一、战术强光LED手电筒方案功能介绍 户外使用的LED…

安装Logstash并导入Movielens测试数据集(基于elasticsearch-8.5.2版本)

安装Logstash并导入Movielens测试数据集 0 安装前准备工作 0.1 安装包下载 组件安装包下载地址Logstashlogstash-8.5.2-linux-x86_64.tar.gzelastic官网&#xff1a;https://www.elastic.co/cn/downloads/past-releases#logstash elastic中文社区&#xff1a;https://elasti…

第六届中国软件开源创新大赛-openGauss赛道全面开启

第六届“中国软件开源创新大赛”在国家自然科学基金委信息科学部的指导下&#xff0c;由中国计算机学会&#xff08;CCF&#xff09;主办&#xff0c;西北工业大学、绿色计算产业联盟、CCF 开源发展委员会联合承办。旨在为国内开源社区提供展示、交流、合作的平台&#xff0c;激…

实力出圈!联诚发LED屏与xr虚拟拍摄解决方案亮相文博会!

六月初夏的深圳&#xff0c;正迎来一场文化产业界的盛事。6月7日&#xff0c;为期5天的第十九届中国(深圳)国际文化产业博览交易会(下称“文博会”)正式拉开帷幕。联诚发LCF作为国家级高新技术企业、国家级专精特新小巨人企业&#xff0c;以及优秀的LED显示与数字装备企业代表亮…

03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素

2.功能元素 1.hgroup 对网页或区段&#xff08;section&#xff09;的标题进行组合 2.figure <figure> 标签规定独立的流内容&#xff08;图像、图表、照片、代码等等&#xff09;。 figure 元素的内容应该与主内容相关&#xff0c;但如果被删除&#xff0c;则不应对…

如何申请项目管理专业人员能力等级评价(CSPM)?

2021年10月&#xff0c;中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系&#xff0c;开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会&#xff08;CAS&#xff09;组织开展的项…

“智慧水利”发展综述:我国水利事业迈入新阶段

6月7日-9日&#xff0c;“2023中国水博览会暨中国&#xff08;国际&#xff09;水务高峰论坛”上&#xff0c;“智慧水利”再次成为热议话题。 智慧水利是在以智慧城市为代表的智慧型社会建设中产生的相关先进理念和高新技术在水利行业的创新应用&#xff0c;是云计算、大数据、…

泰山信息科技5周年:无尽的感恩,非常非常的惋惜

去年的时候&#xff0c;庆贺4周年&#xff0c;公司员工一起去某个地方玩&#xff08;确实没吃到什么东西&#xff09;。这是当时的情形&#xff1a; 因为各种原因&#xff0c;今年3月无锡研发基地解散。作为技术总监&#xff0c;我是非常非常的惋惜。因为我真的想把泰山OFFICE做…

T2-U开发板实现红外遥控接收与发送

文章目录 一、红外概况二、发射1. 调制2. 红外传输协议3. 编码 三、接收四、T2-U开发板硬件连接五、TuyaOS红外功能介绍红外接收功能 六、红外功能代码使用流程1. 硬件注册2. 设备查找3. 打开设备4. 红外发送5. 红外接收6. 接收回调注册 红外遥控是利用近红外光进行数据传输的一…

如何做好功能测试,看这几点就够了

关于新人如何做好功能测试&#xff0c;以下是我个人的一些思考。 01、测试基础的重要性 作为一名测试新人&#xff0c;测试基础非常非常重要。这里说的基础&#xff0c;不仅仅是什么是软件测试、软件测试的目的&#xff0c;而是测试用例的设计能力。 因工作的原因&#xff0…

进程信号以及用户态和内核态的理解

文章目录 什么是进程信号&#xff1f;用户层产生信号的方式有哪些&#xff1f;信号在内核的存在形式认识信号的一些接口信号处理的执行流程理解用户态和内核态信号处理流程 什么是进程信号&#xff1f; 进程信号是一种事件异步通知机制&#xff0c;属于软件中断&#xff08;因…