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重…...
别再手动写RAM/ROM了!用Xilinx Block Memory Generator IP核的5个实战技巧(附Vivado仿真代码)
别再手动写RAM/ROM了!用Xilinx Block Memory Generator IP核的5个实战技巧(附Vivado仿真代码) 在FPGA开发中,存储器模块的设计往往占据大量时间。许多工程师习惯手动编写RTL代码实现RAM/ROM功能,却忽略了Xilinx提供的B…...
别再只把 AI 当聊天框了!探索 Google DeepMind 的 `agy` 命令行工具与人机协同新姿势
别再只把 AI 当聊天框了!探索 Google DeepMind 的 agy 命令行工具与人机协同新姿势 在 AI 辅助编程(AI Coding)卷到飞起的今天,大部分开发者最习惯的可能还是在 IDE 侧边栏里装个插件,或者在网页端和 AI 缝缝补补地复制…...
2026年geo优化五强厂商技术与服务体系全维度盘点
在生成式 AI 全面接管信息入口的今天,究竟什么是 geo优化,它与传统的搜索排名逻辑有何本质区别?面对流量红利枯竭与 AI 搜索的双重夹击,企业布局 geo优化 的商业紧迫性体现在哪里,不做会面临怎样的增长困境?…...
企业微信 Webhook 回调详解
Webhook 回调,是企业微信自动化开发中最核心的能力之一。很多开发者在做企业微信自动化时,都会先关注“消息发送”。 但真正影响系统自动化能力的,其实是“消息回调”。因为只有实时接收到客户消息、群消息与事件通知,系统才能真正…...
UVa 259 Software Allocation
题目分析 一个计算中心有 101010 台不同的计算机(编号 000 至 999),每台计算机在同一时间只能运行一个应用程序。有 262626 种应用程序,名称分别为 A\texttt{A}A 至 Z\texttt{Z}Z。每天会有用户提交应用程序,同一个应用…...
长期使用Taotoken Token Plan套餐对项目研发成本的控制效果
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期使用Taotoken Token Plan套餐对项目研发成本的控制效果 在项目研发中,大模型API调用成本是预算管理的重要一环。对…...
3个关键步骤:在macOS上制作Windows启动盘的完整指南
3个关键步骤:在macOS上制作Windows启动盘的完整指南 【免费下载链接】windiskwriter 🖥 Windows Bootable USB creator for macOS. 🛠 Patches Windows 11 to bypass TPM and Secure Boot requirements. 👾 UEFI & Legacy Sup…...
王晓玲越“激进”,长安马自达越尴尬:油改电没份,新能源没量
【文/深度评车&财经三剑客】当长安马自达执行副总裁王晓玲喊出"马自达电动化转型,合资中最激进"时,市场的反应却是一阵沉默——因为这句话,怎么听都像是一种自我安慰。 王晓玲的底气有二:一是长安马自达坚持不做油改…...
波兰市场语音本地化迫在眉睫,ElevenLabs波兰语支持深度评测:WAV质量、时延、重音准确率98.7%实测数据曝光
更多请点击: https://kaifayun.com 第一章:波兰市场语音本地化战略紧迫性分析 波兰作为欧盟第六大经济体和中东欧数字化转型先锋,其语音技术采纳率正以年均23.7%的速度攀升。截至2024年Q2,波兰智能音箱渗透率达38%,而…...
游戏开发团队必须立即升级的语音合成栈:Llama-3-TTS开源模型实测对比(RTX 4090 vs. Snapdragon 8 Gen3)
更多请点击: https://codechina.net 第一章:AI语音合成在游戏开发中的应用 AI语音合成(Text-to-Speech, TTS)正深刻重塑游戏叙事、角色交互与本地化工作流。相比传统预录语音,实时TTS可动态生成符合上下文语境、情绪状…...
