8、接口的高级用法

news2024/11/26 4:32:50

1、索引类型

        我们可以使用接口描述索引的类型和通过索引得到的值的类型,比如一个数组[‘a’, ‘b’],数字索引0对应的通过索引得到的值为’a’。我们可以同时给索引和值都设置类型,看下面的示例:

interface RoleDic {
  [id: number]: string;
}
const role1: RoleDic = {
  0: "super_admin",
  1: "admin"
};
const role2: RoleDic = {
  s: "super_admin",  // error 不能将类型"{ s: string; a: string; }"分配给类型"RoleDic"。
  a: "admin"
};
const role3: RoleDic = ["super_admin", "admin"];

        上面的例子中 role3 定义了一个数组,索引为数值类型,值为字符串类型。你也可以给索引设置readonly,从而防止索引返回值被修改。

interface RoleDic {
  readonly [id: number]: string;
}
const role: RoleDic = {
  0: "super_admin"
};
role[0] = "admin"; // error 类型"RoleDic"中的索引签名仅允许读取

        这里有一点需要注意,你可以设置索引类型为 number。但是这样如果你将属性名设置为字符串类型,则会报错;但是如果你设置索引类型为字符串类型,那么即便你的属性名设置的是数值类型,也没问题。因为 JS 在访问属性值的时候,如果属性名是数值类型,会先将数值类型转为字符串,然后再去访问。你可以看下这个例子:

const obj = {
  123: "a", // 这里定义一个数值类型的123这个属性
  "123": "b" // 这里在定义一个字符串类型的123这个属性,这里会报错:标识符“"123"”重复。
};
console.log(obj); // { '123': 'b' }

        如果数值类型的属性名不会转为字符串类型,那么这里数值123和字符串123是不同的两个值,则最后对象obj应该同时有这两个属性;但是实际打印出来的obj只有一个属性,属性名为字符串"123",而且值为"b",说明数值类型属性名123被覆盖掉了,就是因为它被转为了字符串类型属性名"123";又因为一个对象中多个相同属性名的属性,定义在后面的会覆盖前面的,所以结果就是obj只保留了后面定义的属性值。

2、接口继承

        接口可以继承,这和类(类的相关知识,我们会在后面全面详细的学习)一样,这提高了接口的可复用性。来看一个场景:

        我们定义一个Vegetables接口,它会对color属性进行限制。再定义两个接口,一个为Tomato,一个为Carrot,这两个类都需要对color进行限制,而各自又有各自独有的属性限制,我们可以这样定义:

interface Vegetables {
  color: string;
}
interface Tomato {
  color: string;
  radius: number;
}
interface Carrot {
  color: string;
  length: number;
}

        三个接口中都有对color的定义,但是这样写很繁琐,所以我们可以用继承来改写:

interface Vegetables {
  color: string;
}
interface Tomato extends Vegetables {
  radius: number;
}
interface Carrot extends Vegetables {
  length: number;
}
const tomato: Tomato = {
  radius: 1.2 // error  Property 'color' is missing in type '{ radius: number; }'
};
const carrot: Carrot = {
  color: "orange",
  length: 20
};

        上面定义的 tomato 变量因为缺少了从Vegetables接口继承来的 color 属性,从而报错。一个接口可以被多个接口继承,同样,一个接口也可以继承多个接口,多个接口用逗号隔开。比如我们再定义一个Food接口,Tomato 也可以继承 Food

interface Vegetables {
  color: string;
}
interface Food {
  type: string;
}
interface Tomato extends Food, Vegetables {
  radius: number;
}

const tomato: Tomato = {
  type: "vegetables",
  color: "red",
  radius: 1.2
};  // 在定义tomato变量时将继承过来的color和type属性同时声明

3、混合类型接口

        JS 的类型是灵活的。在 JS 中,函数是对象类型。对象可以有属性,所以有时我们的一个对象,它既是一个函数,也包含一些属性。比如我们要实现一个计数器函数,比较直接的做法是定义一个函数和一个全局变量:

let count = 0;
const countUp = () => count++;

但是这种方法需要在函数外面定义一个变量,更优一点的方法是使用闭包:

// javascript
const countUp = (() => {
  let count = 0;
  return () => {
    return ++count;
  };
})();
console.log(countUp()); // 1
console.log(countUp()); // 2

        在 TypeScript3.1 版本之前,我们需要借助命名空间来实现。但是在 3.1 版本,TypeScript 支持直接给函数添加属性,虽然这在 JS 中早就支持了:

// javascript
let countUp = () => {
  return ++countUp.count;
};
countUp.count = 0;
console.log(countUp()); // 1
console.log(countUp()); // 2

        我们可以看到,我们把一个函数赋值给countUp,又给它绑定了一个属性count,我们的计数保存在这个 count 属性中。我们可以使用混合类型接口来指定上面例子中 countUp 的类型:

interface Counter {
  (): void; // 这里定义Counter这个结构必须包含一个函数,函数的要求是无参数,返回值为void,即无返回值
  count: number; // 而且这个结构还必须包含一个名为count、值的类型为number类型的属性
}
const getCounter = (): Counter => { // 这里定义一个函数用来返回这个计数器
  const c = () => { // 定义一个函数,逻辑和前面例子的一样
    c.count++;
  };
  c.count = 0; // 再给这个函数添加一个count属性初始值为0
  return c; // 最后返回这个函数对象
};
const counter: Counter = getCounter(); // 通过getCounter函数得到这个计数器
counter();
console.log(counter.count); // 1
counter();
console.log(counter.count); // 2

        上面的例子中,getCounter函数返回值类型为Counter,它是一个函数,无返回值,即返回值类型为void,它还包含一个属性count,属性返回值类型为number

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

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

相关文章

现在的00后,真是卷死了呀,想离职了·····

都说00后躺平了,但是有一说一,该卷的还是卷。这不,刚开年我们公司来了个00后,工作没两年,跳槽到我们公司起薪23K,都快接近我了。 后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。 …

Spring Aop原理全面详解汇总

文章目录 近期想法什么是AOPSpringAOP与AspectjSpringAOP体系概述概念详解连接点- Jointpoint切入点- Pointcut通知- Advice切面- Aspect织入- Weaving 实现原理—动态代理JDK动态代理描述原理代码示例注意执行结果 优点缺点 CGLib动态代理描述原理代码示例注意执行结果 优点缺…

《数理天地》期刊简介及投稿邮箱

《数理天地》期刊简介及投稿邮箱 《数理天地》用稿以数学、物理、学科交叉、科普等稿件为主,自创刊以来,以新观点、新方法、新材料为主题,坚持"期期精彩、篇篇可读"的理念。数理天地内容详实、观点新颖、文章可读性强、信息量大&a…

操作系统——第一章概论(上)

未闻花名,不见花开 文章目录 1.1.1 操作系统的概念,功能1.1.2 操作系统的特征1.2 操作系统的发展和分类1.3.1 操作系统的运行机制1.3.2 中断和异常 1.1.1 操作系统的概念,功能 通过下图可以发现用户和操作系统是有一部分是相连的&#xff0c…

锁屏密码忘记了?教你40秒破iphone锁屏密码!

案例:iPhone锁屏密码忘记了怎么办? 【求助,昨晚刚改的锁屏密码,今早起来想不起来了。苹果锁屏密码有什么方法可以破解吗?】 当你忘记了iPhone的锁屏密码,可能会感到困惑和无助。本文将介绍40秒破iphone锁屏…

从Redis到KeyDB:实现高可用和高可扩展性的转变

文章目录 从Redis到KeyDB:实现高可用和高可扩展性的转变特点**[线程模型]( )****[链接管理]( )****[锁机制]( )****[Active-Replica]( )** 结语 从Redis到KeyDB:实现高可用和高可扩展性的转变 今天给大家介绍的是KeyDB,KeyDB项目是从redis f…

2023年制造业产品经理NPDP认证报名找弘博创新

产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是…

IO多路复用机制

从阻塞 I/O 到 I/O 多路复用 阻塞IO: 阻塞 I/O,是指进程发起调用后,会被挂起(阻塞),直到收到数据再返回。如果调用一直不返回,进程就会一直被挂起。因此,当使用阻塞 I/O 时&#xff…

【电科复试第一名】23上交819考研经验分享

笔者来自通信考研小马哥23上交819全程班学员 819,上岸经验贴,知无不言 初试第十一,复试第一,总分第七(与第六同分) 考研经历:本科就读与湖南某末985,大学时间没好好学习,天天打王者,玩steam上…

让 ChatGPT 扮演一个艺术家,协助我们生成绘图 prompt

stable-diffusion Prompt 生成 直接生成 按照惯用的扮演思路,我们可以让 ChatGPT 扮演一个艺术家,协助我们生成绘图 prompt。考虑到 ChatGPT 和 DallE 同为 openai 公司产品,且 stable-diffusion 开源模型出现较晚,ChatGPT 训练…

Linux云服务器的使用,以及运行Python程序

目录 1、使用Linux云服务器的软件 2、Linux系统运行Python程序 3、Linux系统查看包、虚拟环境、安装包等 以下几个深度学习服务器都不错:智星云、AutoDL、恒源云 1、使用Linux云服务器的软件 MobaXterm_Personal 推荐MobaXterm_Personal mobaxterm是一款方便网站…

目标追踪deepsort ByteTrack

多目标跟踪算法:DeepSort https://arxiv.org/pdf/1703.07402.pdf https://github.com/ZQPei/deep_sort_pytorch DeepSORT(Deep Learning-based SORT)是一种基于深度学习的多目标跟踪算法,用于在视频序列中跟踪多个目标并进行身份…

[pgrx开发postgresql数据库扩展]4.基本计算函数的编写与性能对比

前言 再次声明: 并不是所有场景都需要(或者适合)用rust来写的,绝大部分操作数据库的功能和计算,用SQL就已经足够了! 本系列中,所有的案例,仅用于说明pgrx的能力,而并非…

Spring依赖注入(DI配置)

Spring依赖注入 1. 依赖注入方式【重点】1.1 依赖注入的两种方式1.2 setter方式注入问题导入引用类型简单类型 1.3 构造方式注入问题导入引用类型简单类型参数适配【了解】 1.4 依赖注入方式选择 2. 依赖自动装配【理解】问题导入2.1 自动装配概念2.2 自动装配类型依赖自动装配…

ThinkPHP模型操作上

ThinkPHP模型操作上 前言模型一、创建模型二、模型操作 总结 前言 在mvc架构中,模型的解释是写逻辑代码的地方,其实还可以这样理解,就是一串操作写在一个模型类中,就是你要完成某一项功能,将这个功能的代码写在一个mod…

chatgpt能做本地化部署,训练私有化学科领域数据吗?-----模型只在工具之上,想法只在算力范围之内

GPTGLM-6B场景应用: 最近,ChatGPT已经火出圈了,一般OpenAI需要梯子,然后需要花钱,导致很多限制,用的很不方便(很希望大厂努力,有国人自己的大语言模型),目前…

Bean 作⽤域和⽣命周期

目录 1.lombok 1.1 1.添加依赖:(pom.xml) 1.2 在实体类上使用lombok提供的注解 1.3 安装插件 2. Bean 的 6 种作⽤域(Scope) 2.1 singleton(默认模式) 2.2 prototype(原型模式…

【EasyPoi实战系列】Spring Boot使用EasyPoi的注解让表格更漂亮以及图片的导出 - 第468篇

历史文章(文章累计460) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 【…

利用电脑和手机MT4平台软件设置报警功能的方法及步骤

使用MT4(MetaTrader 4)的报警功能,就可以在汇率达到指定数值,或者是在EA进场买进或结束交易的时候在手机接受推播通知。即使正在外出,也不会因此而错失机会,也可以借此确认进场交易内容,是相当便…

部署CDN的网站如何找真实IP

部署CDN的网站找真实IP 1.概述 目前很多网站使用了cdn服务,用了此服务 可以隐藏服务器的真实IP,加速网站静态文件的访问,而且你请求网站服务时,cdn服务会根据你所在的地区,选择合适的线路给予你访问,由此达…