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重…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
