当前位置: 首页 > news >正文

TypeScript(四)接口

目录

前言

定义

用法

基本用法

约定规则

属性控制

任意属性

可选属性

只读属性

定义函数

冒号定义

箭头定义

接口类型

函数接口

索引接口

继承接口

类接口

总结


前言

在介绍TS对象类型中,为了让数组每一项更具体,我们使用 string [ ] 表示字符串类型的数组,为了知道函数的参数与返回值,使用 let fn: (a: number, b: number) => number 来表示一个函数类型,那么作为复杂类型,仅仅使用Object表示一个普通对象类型是远远不能满足类型检查以及代码可读性的,有没有一种类型可以用来描述对象的结构呢?

这便是今天的主题:接口

定义

接口(Interface)是一种定义对象形状的方式,它指定了对象具备或拥有哪些属性和方法,可以用来定义对象属性值和属性名的类型。使用接口来定义对象可以使代码更健壮,清晰。与Java的接口不同,TS接口除了能够描述类,还可以描述对象,函数等。

用法

基本用法

接口使用interface作为关键词,与JS中类(class)的写法相似,下面是一个JS类

class Animal {color = "black";showColor = () => this.color
}
console.log(new Animal().showColor());

我们定义了一个Animal类,其中包含1个属性以及1个行为;那么在我们抽象构想这个类时可能只知道它的类型,比如:color可能是字符串类型,showColor函数返回一个颜色字符串;

接口的写法如下

interface 接口名称 {属性名: 属性类型函数名(参数类型列表): 返回值类型
}

让我们稍作改动,用接口的方式实现这个类

interface Animal {color: stringshowColor: () => string
}

怎么样?是不是觉得接口不算太难,只需要仿照class的写法,将类抽象成类的形状(属性的类型),就可以实现一个接口

参照之前基本类型的写法,我们新增一个对象,使用对象实现这个抽象的接口

interface Animal {color: stringshowColor: () => string
}const animal: Animal = {color: "blue",showColor() {return this.color},
}
console.log(animal.showColor());

约定规则

一般我们定义接口时,命名规则是在名称前加 I ,即上述接口名是:IAnimal

在使用接口定义对象时会遇到属性不匹配的情况,比如上述代码我们改成

const animal: Animal = {color: "black",name: "dog",showColor() {return this.color},
}

此时编辑器会提示 name 不在类型 Animal 中
那么我们去掉name和color,只保留showColor函数呢?

const animal: Animal = {showColor() {return this.color},
}

编辑器会提示:类型中缺少属性 color。

或者我们不想修改animal中的color属性,让它始终是black

那么有没有办法使接口支持上述属性的操作呢?请接着往下看

属性控制

在接口中,每个属性都有3种选项,分别是可选,只读,任意;换句话说,接口中的属性可以设置成可变的。

任意属性

在接口定义时,在属性名后面加上索引签名来表示接口可以有任意数量的属性。如:

interface Animal {color: stringshowColor: () => string[key: string]: unknown
}

这个接口可以匹配约定规则中的第一段代码;

tips:索引签名参数(上述代码的key)类型支持number,string,symbol,模板字符;示例如下

interface Animal {[key: symbol | string | number]: unknown
}
const str = "name"
const animal: Animal = {0: "dog",[str]: "dog",[Symbol("name")]: "dog",
}

可选属性

在定义接口时,我们可能无法判断某个属性是否存在。此时一个可选的属性操作可以为我们解决此问题,我们在属性名后面增加一个 ? 问号用于为属性增加可选操作,如:

interface Animal {color?: string
}
const animal: Animal = {color: "black"
}
const animal2: Animal = {}

此时color属性在对象中便可有可无,这个接口可以适配约定规则中的第二段代码。

只读属性

顾名思义,只读属性保证了对象中某个属性只允许读取,不允许修改

interface Animal {readonly color: string
}
const animal: Animal = {color: "black"
}
animal.color = "white"

上述代码中会在编译前报错:无法分配到 color ,因为它是只读属性

在JS中我们同样可以控制对象中属性的只读,即只设置属性get而不使用set操作,代码如下

const animal = {_color: "black",get color() {return this._color}
}
animal.color = "white"

定义函数

函数在接口中有两种表现形式,分别是冒号定义和箭头定义

冒号定义

interface 接口名 {函数名 (参数类型) : 函数返回类型
}

箭头定义

interface 接口名 {函数名: (参数类型) => 函数返回类型
}

接口类型

接口除了上述展示的对象接口外,还有函数接口,索引接口,继承接口,类接口,下面我会一一列举。

函数接口

在对象类型中,我们说到了函数类型的定义的方式有两种分别是Function关键词和 ( )=>void 箭头函数,那么在本文,我们会接触到第三种定义函数的方式,接口

interface IFn {(): void
}

我们通过上述代码实现一个无返回值的函数接口,冒号(:)前面的括号表示参数,后面表示函数返回值,结合之前的知识,我们写一个加法函数

interface IFn {(a: number, b: number): number
}
const add: IFn = (a, b) => {return a + b
}

索引接口

同样在对象类型文章中,我们提到了使用接口定义数组类型

interface IArray {[i: number]: any
}

通过定义索引值 i 的类型为 number 来描述一个数组类型

interface IArray {[i: number]: string
}
const list: IArray = ['a', 'b', 'c']

继承接口

和JS中的类一样,接口类型也可以继承操作,被继承的接口拥有父接口的属性及方法

interface IAnimel {name: string
}
interface IDog extends IAnimel {likeMeat: boolean
}interface IWhiteDog extends IDog {color: string
}const whiteDog: IWhiteDog = {name: "阿黄",likeMeat: true,color: "white"
}

上述代码实现了一个连续的接口继承,子类IWhiteDog拥有父类的属性。

继承接口与继承类不同,接口可以通过多继承实现,上述代码可以修改为以下代码

interface IAnimel {name: string
}
interface IDog {likeMeat: boolean
}interface IWhiteDog extends IAnimel, IDog {color: string
}const whiteDog: IWhiteDog = {name: "阿黄",likeMeat: true,color: "white"
}

需要注意的是,执行多继承时,父接口的属性值可以重复,但类型必须相同

interface IAnimel {name: stringlikeMeat: string
}
interface IDog {likeMeat: boolean
}interface IWhiteDog extends IAnimel, IDog {color: string
}

上述代码会抛错:IAnimel 和 IDog 类型的命名属性 likeMeat 不完全相同

除了上面的继承接口外,TS还有一类继承,那便是接口继承类;TS与其他面向对象语言不同,它支持接口继承类中的属性类型及函数类型

将前面的代码修改一下,便可以达到和上面的代码一样的效果,实现接口对类的继承

class IAnimel {name = "阿黄"
}
class IDog {likeMeat = true
}interface IWhiteDog extends IAnimel, IDog {color: string
}const whiteDog: IWhiteDog = {name: "阿黄",likeMeat: true,color: "white"
}

需要注意的是:接口继承的是类的接口(可以理解为声明类的同时会创建类实例的接口类型,这个接口类型被当做是类的接口),所以接口继承的类实际上是类实例的接口

我们使用以下代码可以证实上面的说法

class IDog {static _likeMeat = truelikeMeat = false
}interface IWhiteDog extends IDog {color: string
}const whiteDog: IWhiteDog = {likeMeat: true,_likeMeat: true,color: "white"
}

上述代码的抛错: 

说明接口可以继承类实例的属性,却不可以继承类中的静态属性

类接口

接口是一种抽象的类型,它的作用是描述对象的形状,增强可读性和可维护性。在接口与类之间,TS提供了一个 实现 (implements)关键词区别于传统的冒号(:)赋予类型,下面是一个类接口的例子

interface IAnimel {name: stringreadonly color: stringgetColor: () => stringgetName?(): string
}
class Animal implements IAnimel {name = "dog"color = "black"getColor = () => this.color
}

看到这里不知道你是否会有疑问:接口可以描述类中的属性,那是否可以对构造函数进行描述?

答案是可以,但是和常规写法稍有不同。我们在接口中使用new表示类中的constructor

interface IAnimel {name: stringnew(name: string): Animal
}

然而上面接口的写法无法使用类来实现

interface IAnimel {name: stringnew(name: string): Animal
}
class Animal implements IAnimel {name: string;constructor(name) {this.name = name}
}

为什么会抛错呢?

参考之前的一篇文章:JS继承,因为在TS的类型中,类的构造函数和实例是两个不同的类型:构造函数是一个特殊的函数,它在创建类的实例时被调用,并返回一个该类的实例;类的实例则包含了类的所有属性和方法

有没有使我们实现接口的同时对构造函数进行描述的方法呢?

且看下面的代码

interface IAnimel {// 描述实例name: string
}
interface IAnimelConstructor {// 描述构造函数new(name: string): Animal
}
class Animal implements IAnimel {// 实现接口name: string;constructor(name) {this.name = name}
}
const createAnimal = (__Animal: IAnimelConstructor): IAnimel => {// 工厂模式解决接口的局限性return new __Animal('dog')
}
const animal = createAnimal(Animal)
console.log(animal);

代码中我使用两个接口来描述一个类的构造函数及实例,使用工厂模式解决接口的局限

总结

本文讲述了TypeScript中的接口类型,从定义,意义,用法,属性特性,继承,接口实现及局限性这几个方面详细的介绍了接口,通过代码案例了解其具体用法

感谢你看到了这里,如果文章对你有帮助,希望支持一下博主,谢谢。

参考文章

TypeScript 入门教程

Introduction - TypeScript 精通指南

相关文章:

TypeScript(四)接口

目录 前言 定义 用法 基本用法 约定规则 属性控制 任意属性 可选属性 只读属性 定义函数 冒号定义 箭头定义 接口类型 函数接口 索引接口 继承接口 类接口 总结 前言 在介绍TS对象类型中,为了让数组每一项更具体,我们使用 string [ ]…...

Python-基础知识

目录 Python 简介 Python 发展历史 Python 特点 Python 标识符 Python 保留字符 行和缩进 多行语句 Python 引号 Python注释 Python 简介 Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性,相比…...

【java基础】集合基础说明

文章目录基本介绍Collection接口Iterator和Iterable接口Map接口关于Iterator接口的一些说明框架中的接口具体集合总结基本介绍 集合就是存储用来存储一系列数据的一种数据结构。在这篇文章中会介绍集合的一些基本概念。 Collection接口 集合的基本接口是Collection接口&…...

MySQL的下载及安装详细教程

提示:本文仅为MySQL初学者的安装MySQL过程提供参考,创作不易,请多点赞支持! MySQL的下载及安装前言一、MySQL的下载及安装1.MySQL的下载2.MySQL的安装3.配置环境变量4.连接MySQL4.1 方式一4.2 方式二前言 本文内容主要是帮助初学…...

SSL/TLS协议工作原理

SSL/TLS协议工作原理 SLL/TLS协议工作在应用层和传输层之间,应用层数据需要经过SSL/TLS层的加密之后才会发送到传输层。SSL/TLS协议有两个重要协议:握手协议、记录协议。 1. 握手协议 TCP三次握手完成后,才能进行SSL/TLS的握手。 因为&#…...

大数据项目实战之数据仓库:用户行为采集平台——第4章 用户行为数据采集模块

第4章 用户行为数据采集模块 4.1 数据通道 4.2 环境准备 4.2.1 集群所有进程查看脚本 1)在/home/atguigu/bin目录下创建脚本xcall [atguiguhadoop102 bin]$ vim xcall2)在脚本中编写如下内容 #! /bin/bashfor i in hadoop102 hadoop103 hadoop104 d…...

《统计学习方法》(李航)——学习笔记

第一章 概论统计学习,又称统计机器学习(机器学习),现在提到的 机器学习 往往指的就是 统计机器学习。统计学习研究的对象是数据,其对数据的基本假设是同类数据存在一定的统计规律性,因此可以用概率统计方法…...

阿里云EMR集群搭建及使用

目录 1.简介 1.什么是EMR 2.组成 3.与自建hadoop集群对比 4.产品架构 2.使用 1.创建EMR集群 1.登录EMR on ECS控制台 2.软件设置 3.硬件设置 3.基础配置 2.配置 1.组件配置 2.用户管理 3.安全组 4.Gateway 3.组件UI 1.简介 1.什么是EMR EMR是运行在阿里云平台…...

学习streamlit-4

st.slider 今天学习st.slider滑块组件的使用。 st.slider滑块组件通常被用来作为应用的输入,支持整数、浮点数、日期、时间和日期时间。 下面的示例程序包含以下简单功能,以演示st.slider滑块组件: 用户通过调整滑块选择值应用打印出所选…...

高级Oracle DBA面试题及答案

作为高级 Oracle DBA,您将负责 Oracle 数据库基础架构的设计、安装、配置、监控和维护。您还将负责制定和实施备份和恢复计划,并确保数据的安全性和完整性。要成功担任此职位,您需要对 Oracle 数据库架构有深入的了解,并能够有效地…...

程序员成长路线

程序员在成长的过程中,不同的阶段,需要关注的问题点一会都会有所不同,今天给大家分享下自己的感受。 0-1年,入门,掌握语言基础、提高工具的使用熟练度。 工作第一年,主要围绕ssm三件套、mysql、red…...

【Galois工具开发之路】关于类的重新装载思路

思路 当一个java的类文件发生变更,如果动态的热更新这个新的类文件?目前来说,有两种可能的方式 新增一个自定义ClassLoader,名为NC,让NC去load这个新的类文件,这样就完成了新的类定义的替换 但目前Java有…...

哪款蓝牙耳机音质好?内行推荐四款高音质蓝牙耳机

蓝牙耳机经过近几年的快速发展,在音质上的表现也越来越好。哪款蓝牙耳机音质好?最近看到很多人问。接下来,我来给大家推荐四款高音质蓝牙耳机,可以当个参考。 一、南卡小音舱蓝牙耳机 参考价:246 发声单元&#xff…...

Android程序自动在线升级安装

安卓小白分享: Android程序自动在线升级安装.(通过GetSharedDownloadsPath方法) 1>.修改AndroidManifest.template.xml ( 此文件在你DELPHI项目的目录中,如找不到就文件查找吧) 最好把此文件拖到DELPHI, 用DELPHI打开,(这样,它会一行一行格式清楚) 找到文字<%u…...

JS的BroadcastChannel与MessageChannel

BroadcastChannel与MessageChannel BroadcastChannel BroadcastChannel以广播的形式进行通信 BroadcastChannel用于创建浏览器标签页之间的通信 使用BroadcastChannel的浏览器标签页面必须要遵循同源策略 页面1使用BroadcastChannel创建一个频道&#xff0c;页面2使用Broadc…...

nextjs开发 + vercel 部署 ssr ssg

前言 最近想实践下ssr 就打算用nextjs 做一个人博客 &#xff0c; vercel 部署 提供免费域名&#xff0c;来学习实践下ssr ssg nextjs 一个轻量级的react服务端渲染框架 vercel 由 Next.js 的创建者制作 支持nextjs 部署 免费静态网站托管 初始化项目 npx create-next-app p…...

Good Idea, 利用MySQL JSON特性优化千万级文库表

&#x1f473;我亲爱的各位大佬们好&#x1f618;&#x1f618;&#x1f618; ♨️本篇文章记录的为 利用MySQL JSON特性优化千万级文库表 相关内容&#xff0c;适合在学Java的小白,帮助新手快速上手,也适合复习中&#xff0c;面试中的大佬&#x1f649;&#x1f649;&#x1f…...

【python游戏制作】快来跟愤怒的小鸟一起攻击肥猪们的堡垒吧

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 为了防止/报复偷走鸟蛋的肥猪们&#xff0c;鸟儿以自己的身体为武器&#xff0c; 仿佛炮弹一样去攻击肥猪们的堡垒&#xff0c;保卫自己的鸟蛋 这个游戏大家没玩过的想必也听说过~ 今天就给大家分享一下用python写的愤怒的…...

ARM 学习(一)

ARM 处理器的运行模式ARM处理器共有7种运行模式&#xff0c;如下表所示&#xff1a;处理器模式描述用户模式&#xff08;User&#xff09;正常程序运行模式中断模式&#xff08;IRQ&#xff09;用于通常的中断处理快速中断模式&#xff08;FIQ&#xff09;用于高速传输和通道处…...

深入分析Java的序列化与反序列化

序列化是一种对象持久化的手段。普遍应用在网络传输、RMI等场景中。本文通过分析ArrayList的序列化来介绍Java序列化的相关内容。主要涉及到以下几个问题&#xff1a; 怎么实现Java的序列化 为什么实现了java.io.Serializable接口才能被序列化 transient的作用是什么 怎么自…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...

RLHF vs RLVR:对齐学习中的两种强化方式详解

在语言模型对齐&#xff08;alignment&#xff09;中&#xff0c;强化学习&#xff08;RL&#xff09;是一种重要的策略。而其中两种典型形式——RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff09; 与 RLVR&#xff08;Reinforcement Learning with Ver…...