TypeScript语法解析与进阶扩展

TypeScript

  • 1、类型别名
  • 2、字符串字面量类型
  • 3、元组
  • 4、枚举
  • 5、类
    • 5.1、public private protected
    • 5.2、readonly
    • 5.3、抽象类
    • 5.4、静态成员
    • 5.5、类实现接口
    • 5.6、接口继承接口
    • 5.7、接口继承类
  • 6、泛型
    • 6.1、多个类型参数
    • 6.2、泛型约束
    • 6.3、泛型接口
    • 6.4、泛型类
    • 6.5、泛型参数的默认类型

1、类型别名

类型别名用来给一个类型起个新名字。使用 type 创建类型别名

// 给String类型起别名为s
type s = String;
let str1: s = "123";let all: string|number|boolean
let a: all = 123
let b: all = true

类型别名常用于联合类型。

2、字符串字面量类型

字符串字面量类型用来约束取值只能是某几个字符串中的一个。

let name = "张三" | "张三丰" | "张大炮"
let a: name = "张三"

上例中,我们使用 type 定了一个字符串字面量类型name,它只能取三种字符串中的一种。

注意,类型别名与字符串字面量类型都是使用 type 进行定义。

3、元组

数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。例如定义一对值分别为 stringnumber 的元组:

// 需要按照顺序
let tom: [string, number] = ['Tom', 25];
// 给元组添加内容(不用按照顺序)
tom.push(15888888);
tom.push("秦");

4、枚举

枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。枚举使用 enum 关键字来定义:

enum Color {Red, // 0Green, // 1Blue, // 2
}

上面示例声明了一个 Enum 结构Color,里面包含三个成员RedGreenBlue。第一个成员的值默认为整数0,第二个为1,第二个为2,以此类推。

使用时,调用 Enum 的某个成员,与调用对象属性的写法一样,可以使用点运算符,也可以使用方括号运算符。

let c = Color.Green; // 1
// 等同于
let c = Color["Green"]; // 1

枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射:

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 0); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // trueconsole.log(Days[0] === "Sun"); // true
console.log(Days[1] === "Mon"); // true
console.log(Days[2] === "Tue"); // true
console.log(Days[6] === "Sat"); // true

5、类

5.1、public private protected

TypeScript 可以使用三种访问修饰符,分别是 publicprivateprotected

  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public
  • private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
  • protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的
class Animal {public name;// 构造函数,创建类的时候会自动调用  public constructor(name) {this.name = name;}
}let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom

上面的例子中,name 被设置为了 public,所以直接访问实例的 name 属性是允许的。很多时候,我们希望有的属性是无法直接存取的,这时候就可以用 private 了:

class Animal {private name;public constructor(name) {this.name = name;}
}let a = new Animal('Jack');
console.log(a.name); // error

当构造函数修饰为 private 时,该类不允许被继承或者实例化:

class Animal {public name;private constructor(name) {this.name = name;}
}
class Cat extends Animal {constructor(name) {super(name);}
}let a = new Animal('Jack');

当构造函数修饰为 protected 时,该类只允许被继承。

5.2、readonly

只读属性关键字,只允许出现在属性声明或索引签名或构造函数中。

class Animal {readonly name;public constructor(name) {this.name = name;}
}let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom'; // error

5.3、抽象类

abstract 用于定义抽象类和其中的抽象方法

abstract class Animal {public name;public constructor(name) {this.name = name;}public abstract sayHi();
}class Cat extends Animal {public sayHi() {console.log(`Meow, My name is ${this.name}`);}
}let cat = new Cat('Tom');
  • 抽象类是不允许被实例化的
  • 抽象类中的抽象方法必须被子类实现

给类加上 TypeScript 的类型很简单,与接口类似:

class Animal {name: string;constructor(name: string) {this.name = name;}sayHi(): string {return `My name is ${this.name}`;}
}let a: Animal = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack

5.4、静态成员

类的内部可以使用static关键字,定义静态成员。静态成员是只能通过类本身使用的成员,不能通过实例对象使用。

class MyClass {static x = 0;static printX() {console.log(MyClass.x);}
}MyClass.x; // 0
MyClass.printX(); // 0

上面示例中,x是静态属性,printX()是静态方法。它们都必须通过MyClass获取,而不能通过实例对象调用。

static关键字前面可以使用 public、private、protected 修饰符。

class MyClass {private static x = 0;
}MyClass.x; // 报错

上面示例中,静态属性x前面有private修饰符,表示只能在MyClass内部使用,如果在外部调用这个属性就会报错。

5.5、类实现接口

实现(implements)是面向对象中的一个重要概念。一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性。

一个类可以实现多个接口:

interface Alarm {alert(): void;
}interface Light {lightOn(): void;lightOff(): void;
}class Car implements Alarm, Light {alert() {console.log('Car alert');}lightOn() {console.log('Car light on');}lightOff() {console.log('Car light off');}
}

上例中,Car 实现了 AlarmLight 接口,既能报警,也能开关车灯。

5.6、接口继承接口

接口与接口之间可以是继承关系:

interface Alarm {alert(): void;
}interface LightableAlarm extends Alarm {lightOn(): void;lightOff(): void;
}

这很好理解,LightableAlarm 继承了 Alarm,除了拥有 alert 方法之外,还拥有两个新方法 lightOnlightOff

5.7、接口继承类

常见的面向对象语言中,接口是不能继承类的,但是在 TypeScript 中却是可以的:

class Point {x: number;y: number;constructor(x: number, y: number) {this.x = x;this.y = y;}
}interface Point3d extends Point {z: number;
}let point3d: Point3d = {x: 1, y: 2, z: 3};

6、泛型

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

function createArray<T>(length: number, value: T): Array<T> {let result: T[] = [];for (let i = 0; i < length; i++) {result[i] = value;}return result;
}createArray<string>(3, 'x'); // ['x', 'x', 'x']

上例中,我们在函数名后添加了 <T>,其中 T 用来指代任意输入的类型,在后面的输入 value: T 和输出 Array<T> 中即可使用了。接着在调用的时候,可以指定它具体的类型为 string

6.1、多个类型参数

定义泛型的时候,可以一次定义多个类型参数:

function swap<T, U>(tuple: [T, U]): [U, T] {return [tuple[1], tuple[0]];
}swap([7, 'seven']); // ['seven', 7]

上例中,我们定义了一个 swap 函数,用来交换输入的元组。

6.2、泛型约束

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法:

function loggingIdentity<T>(arg: T): T {// errorconsole.log(arg.length);return arg;
}

上例中,泛型 T 不一定包含属性 length,所以编译的时候报错了。

这时,我们可以对泛型进行约束,只允许这个函数传入那些包含 length 属性的变量。这就是泛型约束:

interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);return arg;
}

上例中,我们使用了 extends 约束了泛型 T 必须符合接口 Lengthwise 的形状,也就是必须包含 length 属性。

6.3、泛型接口

可以使用含有泛型的接口来定义函数的形状:

interface CreateArrayFunc<T> {(length: number, value: T): Array<T>;
}

6.4、泛型类

与泛型接口类似,泛型也可以用于类的类型定义中:

// 泛型数字类
class GenericNumber<T> {zeroValue: T;add: (x: T, y: T) => T;
}// 新创建泛型数字类,给泛型的类型是 number
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; 
};

6.5、泛型参数的默认类型

在 TypeScript 2.3 以后,我们可以为泛型中的类型参数指定默认类型。当使用泛型时没有在代码中直接指定类型参数,从实际值参数中也无法推测出时,这个默认类型就会起作用。

function createArray<T = string>(length: number, value: T): Array<T> {let result: T[] = [];for (let i = 0; i < length; i++) {result[i] = value;}return result;
}

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

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

相关文章

Veeam Backup Enterprise Manager身份验证绕过漏洞(CVE-2024-29849)

一、漏洞概述【漏洞通告】 漏洞名称 Veeam Backup Enterprise Manager身份验证绕过漏洞 CVE ID CVE-2024-29849 漏洞类型 身份验证绕过 发现时间 2024-05-22 漏洞评分 9.8 漏洞等级 严重 攻击向量 网络 所需权限 无 利用难度 低 用户交互 无 PoC/EXP 已…

PostgreSQL源码分析——initdb

数据库初始化 在安装完数据库后&#xff0c;需要进行初始化数据库操作&#xff0c;对应PostgreSQL数据库中就是需要进行initdb后&#xff0c;才能对数据库进行启动。initdb的过程&#xff0c;其实就是创建数据库实例的过程&#xff0c;生成模板数据库和相应的目录、文件信息&a…

uniapp小程序限制微信群访问(图文教程)

我有一个微信小程序 “程序员实用资源” 我现在只想让我的微信群可以访问这个小程序的所有功能 所以我必须对我小程序的来源进行限制&#xff0c;让部分功能在正常访问的时候提示没有加群&#xff0c;不可访问&#xff0c;只有从群内点击进入小程序的时候才可以访问这部分功能…

目标检测顶会新成果!20个突破性方法,更高性能,更强理解与分析能力!

【目标检测】在近年来的深度学习领域中备受关注&#xff0c;它通过识别和定位图像中的目标对象&#xff0c;提升了模型在图像理解和分析方面的能力。目标检测技术在自动驾驶、安防监控和医疗影像分析等任务中取得了显著成果。其独特的方法和卓越的表现使其成为研究热点之一。 为…

ESP32蓝牙串口通讯

文章目录 一、前言二、代码三、运行 一、前言 ESP32支持经典蓝牙和低功耗蓝牙&#xff08;BLE&#xff09;,经典蓝牙可在计算机上模拟出一个串口&#xff0c;使得ESP32可以以串口的方式和计算机通信。 二、代码 #include "BluetoothSerial.h"String device_name …

2025计算机毕业设计选题题目推荐-毕设题目汇总大全

选题在于精&#xff0c;以下是推荐的容易答辩的选题&#xff1a; SpringBoot Vue选题: 基于SpringBoot Vue家政服务系统 基于SpringBoot Vue非物质文化遗产数字化传承 基于SpringBoot Vue兽医站管理系统 基于SpringBoot Vue毕业设计选题管理系统 基于SpringBoot Vue灾害应急救援…

004 AOP使用

文章目录 基于AspectJ的AOP的使用添加依赖编写目标类和目标方法使用XML实现实现步骤切入点表达式通知类型 使用注解实现实现步骤环绕通知注解配置定义通用切入点 纯注解方式 基于AspectJ的AOP的使用 其实就是指的SpringAspectJ整合&#xff0c;不过Spring已经将AspectJ收录到自…

软考中级证在手里,感觉白躺家里了?

软考中级&#xff0c;最适合考的专业是《系统集成项目管理工程师》&#xff0c;特别适合零基础的人&#xff01; 2022年中级职称的报名条件和要求非常宽松&#xff0c;即使没有学历、零基础和相关工作经验也可以考试&#xff01;&#xff01;&#xff01; 一、职称的含金量 …

docker 中 File Sharing 和Volumes 的区别

在 Docker 中&#xff0c;File Sharing 和 Volumes 都涉及到将文件和目录从主机系统映射到容器中&#xff0c;但它们的用途和实现方式有一些重要的区别&#xff1a; 一、简介 File Sharing 是 Docker Desktop 在 Windows 和 macOS 上的一项功能&#xff0c;允许你将主机文件系…

中国最厉害的改名大师颜廷利:食物的真正人生意义是识悟

在探索人生意义的深邃征途中&#xff0c;我们本应以“识悟”为航标&#xff0c;不断扬帆远航&#xff0c;以实现自我的升华。然而&#xff0c;当回望人世繁华&#xff0c;古往今来&#xff0c;无论男女老少&#xff0c;似乎都在“食物”的陪伴下&#xff0c;徘徊往复&#xff0…

计算机网络复习

2024年whut 概述 1.计算机网络的目标&#xff1a;信息传输和资源共享 2.网络协议的要素&#xff08;必考&#xff09;&#xff1a; 语法&#xff1a;数据信息和控制信息的结构或格式 语义&#xff1a;要发出何种控制信息&#xff0c;完成何种动作&#xff0c;做出何种响应 同…

safari浏览器无法连接到服务器

问题&#xff1a;MacBook pro&#xff0c;网络连接正常&#xff0c;可以使用各种软件上网&#xff0c;唯独safari浏览器打不开网页&#xff0c;报错说Safari无法连接到服务器&#xff1b; 原因&#xff1a;使用了VPN&#xff0c;VPN自动更改了网络设置&#xff0c;导致Safari浏…

监控局域网电脑屏幕的办法,最简单的三种方法,好用!

在现代企业管理和家庭教育环境中&#xff0c;对局域网内电脑屏幕进行有效监控成为了保障信息安全、提升工作效率和监督行为规范的重要手段。 监控局域网电脑屏幕不仅可以帮助管理者了解员工的工作状态&#xff0c;确保资源的合理使用&#xff0c;还能在一定程度上预防潜在的网…

银行卡归属地查询-银行卡归属地接口-银行卡归属地API

接口简介&#xff1a;通过银行卡号查询国内外银行名称、银行卡卡种、卡品牌以及银行卡发卡省份和城市&#xff0c;支持借记卡和部分贷记卡的发卡省市查询。 若银行卡是农村信用社&#xff0c;归属地无法区分到城市&#xff0c;只能到省份 接口地址&#xff1a;https://www.wapi…

CentOS 7 安装MySQL以及常见问题解决

访问网站&#xff1a;http://repo.mysql.com 找到适配CentOS 7版本的MySQL 的YUM仓库包rpm文件&#xff0c;如下图 下载后&#xff0c;找到安装包的位置 空白处右键&#xff0c;选择在终端打开 查看当前目录下文件 # 安装MySQL 5.7的YUM仓库包rpm -ivh mysql57-community-rele…

js的导入导出

js 的导入导出 在 JavaScript 中&#xff0c;可以使用 import 关键字来导入其他模块或文件。而使用 export 关键字则可以将变量、函数等内容从当前模块导出供其他地方引用。 下面是一些示例代码&#xff1a; 导入模块&#xff1a; // 导入名为 "module" 的模块 i…

中科数安 | 加密管理系统

中科数安提供的加密管理系统是一套全面而高效的数据安全解决方案&#xff0c;旨在保护企业核心文件资料的安全。该系统结合了多种先进的技术手段和管理策略&#xff0c;确保企业数据在存储、传输和使用过程中都得到严格的保护。 www.weaem.com 以下是中科数安加密管理系统的主要…

固定式土壤墒情监测仪—土壤状况进行长期跟踪和分析

TH-TS600 固定式土壤墒情监测仪是一种专门用于长期、连续、自动监测土壤墒情的设备。能够实时监测土壤的水分、温度、湿度等关键参数&#xff0c;确保农民和管理者能即时获取土壤状况信息&#xff0c;便于及时做出农业决策。由于是自动监测&#xff0c;数据采集的准确性和可靠性…

比较器是什么比较器和运放的区别

比较器是一种能够对两个或多个数据项进行比较&#xff0c;以确定它们是否相等、大小关系及排列顺序的电路或装置。它通常用于将一个模拟电压信号与一个基准电压进行比较&#xff0c;当输入电压的差值增大或减小且正负符号不变时&#xff0c;其输出保持恒定。比较器的两路输入为…

[答疑]订单、预约单的流水号是冗余属性吗

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 陈磊 2024-6-12 20:40 老师好&#xff01;我学习了软件方法的类图内容&#xff0c;也已经认真做题了&#xff0c;现有一个问题想请老师解惑。 像订单、预约单这样的单据生成的时候&a…