TypeScript 学习之接口
接口:对值所具有的结构进行类型检查,称为“鸭式变型法”或“结构性子类型化”
基本使用
interface LabelledValue {label: string;
}function printLabel(labelledObj: LabelledValue) {console.log(labelledObj.label);
}let myObj = {size: 10, label: 'Size 10 Object'};
printLabel(myObj);
LabelledValue
接口定义了labelledObj
的类型结构。printLabel
调用时传入的参数包含label
属性就可以通过LabelledValue
接口的类型检查。同时类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的,就会通过。
可选属性
接口的某些属性是不必存在的,这时就需要设置为可选属性。
在可选属性名字定义的后面加一个?
符号
interface SquareConfig {color?: string; // 可选属性width?: number; // 可选属性
}function createSquare(config: SquareConfig): {color: string; area: number} {let newSquare = {color: 'white', area: 100};if (config.color) {newSquare.color = config.color;}if (config.width) {newSquare.area = config.width * config.width;}return newSquare;
}let mySquare = createSquare({color: 'black'});
可选属性可以对可能存在的属性进行预定义,也可以捕获引用了不存在的属性时的错误。
只读属性
一些对象属性只能在对象刚刚创建的时候修改其值,可以在属性名前用
readonly
来指定只读属性。
初始化后,只读属性不能再赋值
interface Point {readonly x: number;readonly y: number;
}let p1: Point = {x: 10, y: 20};
p1.x = 5; // Error
ReadonlyArray<T>
只读数组
数组创建后不能被修改
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error
ro.push(5); // error
ro.length = 100; // error
a = ro; // error ReadonlyArray 赋值给一个普通数组是不可以的,可以用类型断言重写:a = ro as number[]
字符串索引签名
interface SquareConfig {color?: string;width?: string;[propName: string]: any; // 字符串索引签名,可以绕过额外类型检查。
}
函数类型
接口表示函数类型,需要给接口定义一个调用签名,就像是一个只有参数列表和返回值类型的函数定义。
对于函数类型的类型检查,函数的参数名不需要与接口里定义的名字相匹配
函数的参数会逐个进行检查,对应位置上的参数类型是兼容的。不指定类型,TypeScript
的类型系统会推断出参数类型。函数的返回值类型是通过其返回值推断出来。
interface SearchFunc {(source: string, subString: string): boolean;
}let mySearch: SearchFunc;
mySearch = function (source: string, subString: string) {let result = source.search(subString);return result > -1;
};
可索引的类型
可索引类型具有一个索引签名,描述了对象索引的类型,还有相应的索引返回值类型。
TypeScript
支持两种索引签名:字符串和数字。可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。
number
去索引时,会先转换成string
,再去索引对象。
interface StringArray {[index: number]: string;
}let myArray: StringArray;
myArray = ['Bob', 'Fred'];let myStr: string = myArray[0];
- 属性类型与索引类型必须匹配
interface NumberDictionary {[index: string]: number;length: number; // 正确,length 是 number 类型name: string; // 错误,`name`的类型与索引类型返回值的类型不匹配
}
- 索引签名设置为只读, 防止给索引赋值
interface ReadonlyStringArray {readonly [index: number]: string;
}let myArray: ReadonlyStringArray = ['Alice', 'Bob'];
myArray[2] = 'Mallory'; // error, 索引签名是只读的
类实现接口
类 实现接口,就要实现接口的属性和方法
接口描述了类的公共部分,不是公共和私有两部分
interface ClockInterface {currentTime: Date;setTime(d: Date);
}class Clock implements ClockInterface {currentTime: Date;setTime(d: Date) {this.currentTime = d;}constructor(h: number, m: number) {}
}
类静态部分和实例部分的区别
类有:静态部分的类型和实例的类型
- 用构造器签名去定义一个接口并视图定义一个类去实现这个接口时会得到一个错误
interface ClockConstructor {new (hour: number, minute: number);
}/*** 类实现一个接口时,只对其实例部分进行类型检查,`constructor`存在于类的静态部分,不在检查范围内。*/
class Clock implements ClockConstructor {currentTime: Date;constructor(h: number, m: numberF) {}
}
- 直接操作类的静态部分
interface ClockConstructor {new (hour: number, minute: number): ClockInterface; // 限制的类的实例化 是 `ClockInterface 的子类实例`
}interface ClockInterface {tick();
}function createClock(ctor: ClockConstructor,hour: number,minute: number,
): ClockInterface {return new ctor(hour, minute);
}class DigitalClock implements ClockInterface {constructor(h: number, m: number) {}tick() {console.log('beep beep');}
}class AnalogClock implements ClockInterface {constructor(h: number, m: number) {}tick() {console.log('tick tick');}
}let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);
因为createClock
的第一个参数是ClockConstructor
类型,在 createClock(AnalogClock,7,32)里,会检查AnalogClock
是否符合构造函数签名
继承接口
- 和类一样,接口也可以相互继承。
interface Shape {color: string;
}interface Square extends Shape {sideLength: number;
}let square = <Square>{};
square.color = 'blue';
square.sideLength = 10;
- 一个接口可以继承多个接口,创建出多个接口的合成接口
interface Shape {color: string;
}interface PenStroke {penWidth: number;
}interface Square extends Shape, PenStroke {sideLength: number;
}let square = <Square>{};
square.color = 'blue';
square.sideLength = 10;
square.penWidth = 5.0;
混合类型
例子:一个对象可以同时作为函数和对象使用,并带有额外的属性
interface Counter {(start: number): string;interval: number;reset(): void;
}function getCounter(): Counter {let counter = <Counter>function (start: number) {// 访问对象里的属性console.log('counter', counter.interval);};counter.interval = 123;counter.reset = function () {};return counter;
}let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
接口继承类
接口继承了一个类类型时,会继承类的成员但不包括其实现。就像接口声明了所有类中存在的成员,但并没有提供具体实现一样。
接口同样会继承到类的private
和protected
成员。所以当一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implements)
class Control {private state: any;
}interface SelectableControl extends Control {select(): void;
}// 子类 Button 继承 `Control` 实现接口`SelectableControl`
class Button extends Control implements SelectableControl {select() {}
}// 继承父类 control
class TextBox extends Control {select() {}
}// 错误:私有的属性只能由自身类或者其子类实现这个接口
// Image 类缺少 Control类的 `state`属性
class Image implements SelectableControl {select() {}
}
相关文章:
TypeScript 学习之接口
接口:对值所具有的结构进行类型检查,称为“鸭式变型法”或“结构性子类型化” 基本使用 interface LabelledValue {label: string; }function printLabel(labelledObj: LabelledValue) {console.log(labelledObj.label); }let myObj {size: 10, label:…...
原码反码补码
在计算机中,负数都是以补码的形式存放的, 正数的原码、反码、补码完全一致。 原码:指的是正数的二进制或负数的二进制, 负数的二进制(原码),其实就是在正数的二进制的最高位前面加一个符号位 1。…...

大数据选股智能推荐系统V1.0-1
很长时间没有发布博客了,这段时间个人确实有点忙。另外一方面在这段时间我也没有闲着。自己研发了一套大数据选股的智能推荐系统。废话不说,我们先来看这套系统:登录页面:(技术点:验证码的生成)…...
调研生成GIF表情包之路
调研阶段 gifshot.js合成GIF 可以从媒体流、视频或图像创建动画 GIF 的 JavaScript 库。 csdn地址:https://blog.csdn.net/qq_16494241/article/details/125717405 分解GIF图片、合成GIF图片 两步走: 1、分解GIF图片 libgif-js:JavaScrip…...
【RocketMQ】源码详解:生产者启动与消息发送流程
消息发送 生产者启动 入口 : org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#start(boolean) 生产者在调用send()方法发送消息之前,需要调用start进行启动, 生产者启动过程中会启动一些服务和线程 启动过程中会启动MQClientInstance, 这个实例是针对一个项…...

信息安全(一)
思维导图 一、AES加解密 1.概述 1.1 概念 AES: 高级加密标准(Advanced Encryption Standard)是一种对称加密的区块加密标准。 (1)替代DES的新一代分组加密算法 (2)支持三种长度密钥&#x…...

企业多会场视频直播(主会场、分会场直播)实例效果
阿酷TONY 2023-2-16 长沙 活动直播做多会场切换功能(主会场、分会场、会场一、会场二、会场三自由切换) 企业多会场视频直播(主会场、分会场直播)实例效果 特点:支持PC端,也支持移动端观看,会…...
线性代数速览(一)行列式
文章目录行列式🌻 行列式的定义🌼 行列式的性质🌷 一些定理🥀 行列式的计算🌺 克莱姆法则行列式 行列式的本质,就是一个数值。 🌻 行列式的定义 有三种定义:1、按行展开ÿ…...

恭喜山东翰林“智慧园区管理系统”获易知微可视化设计大赛二等奖
数字化经济发展是全球经济发展的重中之重,“数字孪生(Digital Twin)”这一词汇正在成为学术界和产业界的一个热点。数字孪生作为近年来的新兴技术,其与国民经济各产业融合不断深化,推动着各大产业数字化、网络化、智能…...
gulp简单使用
gulp gulp的核心理念是task runner 可以定义自己的一系列任务 等待任务被执行 基于文件stream的构建流 我们可以使用gulp的插件体系来完成某些任务 webpack的核心理念是module bundler webpack是一个模块化的打包工具 可以使用各种各样的loader来加载不同的模块 可以使用各种…...

ce认证机构如何选择?
CE认证想必大家都已经有所了解,它是产品进入欧盟销售的通行证,那么我们在办理CE认证时该怎么进行选择?带大家了解一下CE认证机构,以及该怎么去进行选择? 以下信息由证果果编辑整理,更多认证机构信息请到证果果网站查看。找机构…...

全网招募P图高手!阿里巴巴持续训练鉴假AI
P过的证件如何鉴定为真?三千万网友都晒出了与梅西的合影?图像编辑技术的普及让人人都能P图,但也带来“假图”识别难题,甚至是欺诈问题。 为此,阿里安全联合华中科技大学国家防伪工程中心、国际文档分析识别方向的唯一顶…...

webrtc QOS笔记一 Neteq直方图算法浅读
webrtc QOS笔记一 Neteq直方图算法浅读 文章目录webrtc QOS笔记一 Neteq直方图算法浅读Histogram Algorithm获取目标延迟遗忘因子曲线Histogram Algorithm DelayManager::Update()->Histogram::Add() 会根据计算的iat_packet(inter arrival times, 实际包间间隔 / 打包时长…...
细分和切入点
本文重点介绍做SEO网站细分和切入点的方法:当我们的行业和关键词竞争性比较大的时候,我们可以考虑对行业或者产品做细分,从而找到切入点。可以按照以下三个方面进行细分。1、按城市细分例如:A:餐饮培训,当前…...

iOS创建Universal Link
iOS 9之前,一直使用的是URL Schemes技术来从外部对App进行跳转,但是iOS系统中进行URL Schemes跳转的时候如果没有安装App,会提示无法打开页面的提示。 iOS 9之后起可以使用Universal Links技术进行跳转页面,这是一种体验更加完美的…...

RuoYi-Vue搭建(若依)
项目简介 RuoYi-Vue基于SpringBootVue前后端分离的Java快速开发框架1.前端采用Vue、Element UI2.后端采用Spring Boot、Spring Security、Redis & Jwt3.权限认证使用Jwt,支持多终端认证系统4.支持加载动态权限菜单,多方式轻松权限控制5.高效率开发&a…...

进程组和用处
进程组:一个或多个进程的集合,进程组id是一个正整数。组长进程:进程组id 进程id组长进程可以创建一个进程组,创建该进程组的进程,终止了,只要进程组有一个进程存在,进程组就存在,与…...

Nacos集群+Nginx负载均衡
搭建Nacos集群 注意: 3个或3个以上Nacos节点才能构成集群。要求服务器内存分配最好大于6G以上(如果不够则需修改nacos启动脚本中的默认内存配置)根据nacos自带的mysql建库脚本建立对应数据库(/conf/nacos-mysql.sql)如果是三台服…...
TypeScript 学习之类型兼容
TypeScript 的类型兼容性是基于结构子类型的。 结构类型是一种只使用其成员来描述类型的方式。 interface Named {name: string; }class Person {name: string; }let p: Named; p new Person();// 赋值成功,因为都是结构类型,只要Person 类型的包含 Nam…...

Linux软件管理RPM
目录 前言 RPM软件管理程序:rpm RPM默认安装的路径 PRM讲解前准备工作 RPM安装(install) RPM查询(query) RPM卸载(erase) RPM升级与更新(upgrade/freshen) RPM重…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...