3、Typescript中补充的六个类型

news/2024/4/27 10:56:06/文章来源:https://blog.csdn.net/qq_37165235/article/details/130267167

1、元组

        元组可以看做是数组的拓展,它表示已知元素数量和类型的数组。确切地说,是已知数组中每一个位置上的元素的 类型,来看例子:

let tuple: [string, number, boolean];
tuple = ["a", 2, false];
tuple = [2, "a", false]; // error 不能将类型“number”分配给类型“string”。 不能将类型“string”分配给类型“number”。
tuple = ["a", 2]; // error Property '2' is missing in type '[string, number]' but required in type '[string, number, boolean]'

        可以看到,上面我们定义了一个元组 tuple,它包含三个元素,且每个元素的类型是固定的。当我们为 tuple 赋值 时:各个位置上的元素类型都要对应,元素个数也要一致。我们还可以给单个元素赋值:

tuple[1] = 3;

        这里我们给元组 tuple 的索引为 1 即第二个元素赋值为 3,第二个元素类型为 number,我们赋值给 3,所以没有问题。当我们访问元组中元素时,TypeScript 会对我们在元素上做的操作进行检查:

tuple[0].split(":"); // right 类型"string"拥有属性"split"
tuple[1].split(":"); // error 类型“number”上不存在属性“split”

        上面的例子中,我们访问的 tuple 的第二个元素的元素类型为 number,而数值没有 split 方法,所以会报错。在 2.6 版本之前,TypeScript 对于元组长度的校验和 2.6 之后的版本有所不同,我们来看下面的例子,前后版本对 于该情况的处理:

let tuple: [string, number];
tuple = ["a", 2]; // right 类型和个数都对应,没问题
// 2.6版本之前如下也不会报错
tuple = ["a", 2, "b"];
// 2.6版本之后如下会报错
tuple = ["a", 2, "b"]; // error 不能将类型“[string, number, string]”分配给类型“[string, number]”。 属性“length”的类型不兼容。

        这个赋给元组的值有三个元素,是比我们定义的元组类型元素个数多的:

  • 在 2.6 及之前版本中,超出规定个数的元素称作越界元素,但是只要越界元素的类型是定义的类型中的一种即 可。比如我们定义的类型有两种:string 和 number,越界的元素是 string 类型,属于联合类型 string | number , 所以没问题,联合类型的概念我们后面会讲到。
  • 在 2.6 之后的版本,去掉了这个越界元素是联合类型的子类型即可的条件,要求元组赋值必须类型和个数都对应。

        在 2.6 之后的版本,[string, number]元组类型的声明效果上可以看做等同于下面的声明:

interface Tuple extends Array<number | string> {0: string;1: number;length: 2;
}

        上面这个声明中,我们定义接口 Tuple ,它继承数组类型,并且数组元素的类型是 number 和 string 构成的联合类型,这样接口 Tuple 就拥有了数组类型所有的特性。并且我们明确指定索引为0的值为 string 类型,索引为1的值为 number 类型,同时我们指定 length 属性的类型字面量为 2,这样当我们再指定一个类型为这个接口 Tuple 的时 候,这个值必须是数组,而且如果元素个数超过2个时,它的length就不是2是大于2的数了,就不满足这个接口定义 了,所以就会报错;当然,如果元素个数不够2个也会报错,因为索引为0或1的值缺失。

        如果你想要和 2.6 及之前版本一样的元组特性,那你可以这样定义接口:

interface Tuple extends Array<number | string> {0: string;1: number;
}

        也就是去掉接口中定义的 length: 2 ,这样 Tuple 接口的 length就是从 Array继承过来的 number 类型,而不用必须是 2 了。

2、枚举

        enum 类型在 C++这些语言中比较常见,TypeScript 在 ES 原有类型基础上加入枚举类型,使我们在 TypeScript 中 也可以给一组数值赋予名字,这样对开发者来说较为友好。比如我们要定义一组角色,每一个角色用一个数字代 表,就可以使用枚举类型来定义:

enum Roles {SUPER_ADMIN,ADMIN,USER
}

        上面定义的枚举类型 Roles 里面有三个值,TypeScript 会为它们每个值分配编号,默认从 0 开始,依次排列,所以 它们对应的值是:

enum Roles {SUPER_ADMIN = 0,ADMIN = 1,USER = 2
}

        当我们使用的时候,就可以使用名字而不需要记数字和名称的对照关系了:

const superAdmin = Roles.SUPER_ADMIN;
console.log(superAdmin); // 0

        你也可以修改这个数值,比如你想让这个编码从 1 开始而不是 0,可以如下定义:

enum Roles {SUPER_ADMIN = 1,ADMIN,USER
}

        这样当你访问 Roles.ADMIN时,它的值就是 2 了。你也可以为每个值都赋予不同的、不按顺序排列的值:

enum Roles {SUPER_ADMIN = 1,ADMIN = 3,USER = 7
}

        通过名字 Roles.SUPER_ADMIN 可以获取到它对应的值 1,同时你也可以通过值获取到它的名字,以上面任意数值 这个例子为前提:

console.log(Roles[3]); // 'ADMIN'

3、Any

        JavaScript 的类型是灵活的,程序有时也是多变的。有时,我们在编写代码的时候,并不能清楚地知道一个值到底 是什么类型,这时就需要用到 any 类型,即任意类型。我们来看例子:

let value: any;
value = 123;
value = "abc";
value = false;

        你可以看到,我们定义变量 value,指定它的类型为 any,接下来赋予任何类型的值都是可以的。我们还可以在定义数组类型时使用 any 来指定数组中的元素类型为任意类型:

const array: any[] = [1, "a", true];

        但是请注意,不要滥用 any,如果任何值都指定为 any 类型,那么 TypeScript 将失去它的意义。所以如果类型是未知的,更安全的做法是使用unknown类型。

4、void

        void 和 any 相反,any 是表示任意类型,而 void 是表示没有任意类型,就是什么类型都不是,这在我们定义函 数,函数没有返回值时会用到:

const consoleText = (text: string): void => {console.log(text);
};

        void 类型的变量只能赋值为 undefined 和 null ,其他类型不能赋值给 void 类型的变量、

5、never

        never 类型指那些永不存在的值的类型,它是那些总会抛出异常或根本不会有返回值的函数表达式的返回值类型, 当变量被永不为真的类型保护(后面章节会详细介绍)所约束时,该变量也是 never 类型。这个类型比较难理解,我们先来看几个例子:

const errorFunc = (message: string): never => {throw new Error(message);
};

        这个 errorFunc 函数总是会抛出异常,所以它的返回值类型时 never,用来表明它的返回值是永不存在的。

const infiniteFunc = (): never => {while (true) {}
};

        infiniteFunc 也是根本不会有返回值的函数,它和之前讲 void 类型时的 consoleText 函数不同, consoleText 函数没有返回值,是我们在定义函数的时候没有给它返回值,而 infiniteFunc 是死循环是根本不会返回值的,所以它们二者还是有区别的。

        never 类型是任何类型的子类型,所以它可以赋值给任何类型;而没有类型是 never 的子类型,所以除了它自身没有任何类型可以赋值给 never 类型,any 类型也不能赋值给 never 类型。我们来看例子:

let neverVariable = (() => {while (true) {}
})();
neverVariable = 123; // error 不能将类型"number"分配给类型"never"

        上面例子我们定义了一个立即执行函数,也就是 "let neverVariable = " 右边的内容。右边的函数体内是一个死循环, 所以这个函数调用后的返回值类型为 never,所以赋值之后 neverVariable 的类型是 never 类型,当我们给 neverVariable 赋值 123 时,就会报错,因为除它自身外任何类型都不能赋值给 never 类型。

6、unknown

        unknown类型是TypeScript在3.0版本新增的类型,它表示未知的类型,这样看来它貌似和any很像,但是还是有区别的,也就是所谓的“unknown相对于any是安全的”。怎么理解呢?我们知道当一个值我们不能确定它的类型的时 候,可以指定它是any类型;但是当指定了any类型之后,这个值基本上是“废”了,你可以随意对它进行属性方法的访问,不管有的还是没有的,可以把它当做任意类型的值来使用,这往往会产生问题,如下:

let value: any
console.log(value.name)
console.log(value.toFixed())
console.log(value.length)

        上面这些语句都不会报错,因为value是any类型,所以后面三个操作都有合法的情况,当value是一个对象时,访问 name属性是没问题的;当value是数值类型的时候,调用它的toFixed方法没问题;当value是字符串或数组时获取它的length属性是没问题的。

        而当你指定值为unknown类型的时候,如果没有通过基于控制流的类型断言来缩小范围的话,是不能对它进行任何操作的,unknown类型的值不是可以随便操作的。

7、高级类型

7.1、交叉类型

        交叉类型就是取多个类型的并集,使用 & 符号定义,被&符链接的多个类型构成一个交叉类型,表示这个类型同时 具备这几个连接起来的类型的特点,来看例子:

//交叉类型
interface ClassA{name:string;age:number
}interface ClassB{name:string;phone:number;
}//将接口ClassA和接口ClassB通过&进行合并创建一个新的接口类型Class
type Class = ClassA & ClassB
let info:Class = {name:'zhagsan',age:18,phone:1573875555
}console.log("交叉结果:",info)//交叉结果: {"name": "zhagsan","age": 18,"phone": 1573875555}

要点说明:

任何类型都能通过&合并成新的类型吗?

        这肯定是不行的,原子类型进行合并是没有任何意义,因为它们合并后的类型是never,比如string&number,这肯定是错误的,因为不可能有既满足字符串又满足数字类型。

合并的接口类型中具有同名属性,该怎么处理?

        这里分两种情况,如果同名属性的类型相同则合并后还是原本类型,如果类型不同,则合并后类型为never

interface X{q:number,w:string
}
interface Y{q:boolean,r:string,
}
type XY = X&Y

编辑器中直接就给我们了提示,如下图所示:

 高级示例:

interface A {inner: D;
}
interface B {inner: E;
}
interface C {inner: F;
}interface D {d: boolean;
}
interface E {e: string;
}
interface F {f: number;
}type ABC = A & B & C;
let abc: ABC = {inner: {d: false,e: 'className',f: 5}
};

7.2、联合类型

        联合类型和交叉类型比较相似,联合类型通过|符号连接多个类型从而生成新的类型。它主要是取多个类型的交集,即多个类型共有的类型才是联合类型最终的类型。联合类型可以是多个类型其中一个,可做选择,比如:string | number,它的取值可以是string类型也可以是number类型。举几个例子,如下所示:

  • 声明变量的时候设置变量类型
let a:string|number|boolean;
a = 's';
a = 1;
a= false;
  • 多个接口类型进行联合
interface X{q:number,w:string,r:string
}
interface Y{q:numberr:string,
}
type XY = X | Y
let value:XY = {q:1,r:'r'
}
  • 函数接口类型进行联合
interface X{x:()=>string;y:()=>Number;
}
interface Y{x:()=>string;
}
type XY = X|Y;
function func1():XY{
//此处不进行类型断言为XY在编辑器中会报类型错误return {} as XY}
let testFunc = func1();
testFunc.x();
testFunc.y(); //Error:类型“XY”上不存在属性“y”,类型“Y”上不存在属性“y”。

另外我们还要注意,testFunc.x()还会报类型错误,我们需要用类型守卫来区分不同类型。这里我们用in操作符来判断

if('x' in testFunc) testFunc.x()

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

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

相关文章

网络设备发现工具

什么是网络设备发现 网络设备发现是识别和映射网络基础架构&#xff08;如路由器、交换机、集线器、防火墙、无线接入点、服务器、虚拟机等&#xff09;中存在的设备和接口的过程。网络发现是网络管理的第一步&#xff0c;也是成功监控解决方案的关键。该过程不仅涉及发现网络…

LINUX SVN 新建项目

从第三方代码创建代码库&#xff1a; 1、通过客户端进入服务端 2、在对应的目录创建新的项目/目录 在对应的目录右击 &#xff1a;creat folder... 例&#xff1a;创建testSvn 3、在客户端checkout(co) testSvn 4、将第三方源码(srcTest)拷贝到客户端下的对应路径 防止L…

Cesium 实战-最新版(1.104.0)通过异步方式初始化地球,加载影像以及高程图层

Cesium 实战-最新版&#xff08;1.104.0&#xff09;通过异步方式初始化地球&#xff0c;加载影像以及高程图层 遇到问题初始化底图初始化高程&#xff08;监听载入完成事件&#xff0c;开启关闭高程&#xff09;初始化 3dtile在线示例 Cesium 最新版&#xff08;1.104.0&#…

DIN11系列 大电流输出信号隔离模块线性驱动器0~100mA/0~500mA/0~2A/0-4A

主要特性 精度、线性度误差等级&#xff1a; 0.1、0.2、0.5 级4-20mA/0-5V/0-10V 等标准信号输入0~100mA/0~500mA/0~1A/0-5A 等电流信号输出0~1V(max 5A)/0~10V/0-24V(max 5A) 等电压信号输出信号输入/信号输出 3000VDC 隔离辅助电源&#xff1a;12V、15V 或 24V 直流单电源供…

NeRFStudio系列 Part 1:PipeLines概述

前言&#xff1a;Why NeRFStudio? NeRF社区是近两年来计算机领域最活跃的学术社区之一&#xff0c;各种具有milestone意义的算法层出不穷&#xff0c;各位作者的开源工作也做得非常扎实&#xff0c;非常多的工作都自带了code、data、project page。 但是后继者想要在这些伟大的…

jenkins自动化部署配置

文章目录 1. jenkins 插件安装2. 配置2.1 全局工具配置2.2 全局配置2.2.1 gitee 配置 3. 创建任务添加gitee ssh jenkins 开机自启动 1. jenkins 插件安装 ant Build Failure AnalyzerBuild Monitor ViewBuild Timeout dockerEmail Extension Plugin giteegithubgradle javama…

Python科研数据可视化

在过去的20 年中&#xff0c;随着社会产生数据的大量增加&#xff0c;对数据的理解、解释与决策的需求也随之增加。而固定不变是人类本身&#xff0c;所以我们的大脑必须学会理解这些日益增加的数据信息。所谓“一图胜千言”&#xff0c;对于数量、规模与复杂性不断增加的数据&…

广域通信网 - 流量控制(停等协议、滑动窗口协议)

文章目录 1 概述2 流量控制协议2.1 停等协议2.2 滑动窗口协议 1 概述 #mermaid-svg-c9cNIYsOvLpoO4AV {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-c9cNIYsOvLpoO4AV .error-icon{fill:#552222;}#mermaid-svg-c9c…

跳槽必备,全面总结Android面试知识点

在最近的 Android 开发&#xff08;社招&#xff09;面试中总结的 Android 基础知识点&#xff0c;已经拿到心仪的offer&#xff0c;回馈同学们&#xff0c;感谢其他大佬的分享。 Android中大厂面试都很重视基础知识的考察&#xff0c;面试前不仅要熟悉这些知识点&#xff0c;…

设计模式之访问者模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、访问者模式是什么&#xff1f; 访问者模式是一种行为型的软件设计模式&#xff0c;表示一个作用于某对象结构中的各元素的操作…

智能家居代码架构---简单工厂模式

(11条消息) 智能家居 (10) ——人脸识别祥云平台编程使用(编译libcurl库支持SSL&#xff0c;安装SSL依赖库libssl、libcrypto)openssl 依赖库行稳方能走远的博客-CSDN博客 看上面这个博客的往期文章 代码设计经验的总结&#xff0c;稳定&#xff0c;拓展性更强。一系列编程思…

DAX:概述ALL函数

简单的说&#xff0c;当ALL用作表函数时&#xff0c;忽略应用到表上的任何过滤器&#xff0c;并返回数据表&#xff1b;当ALL用作CALCULATE和CALCULATETABLE函数中修饰器时&#xff0c;ALL函数从扩展表中移除已经应用的过滤上下文。 注意自动存在(auto-eixist)对ALL()函数的影响…

选址-路径问题(Location-Routing Problem, LRP)

今天为大家介绍的是选址-路径问题(Location-Routing Problem, LRP)&#xff0c;首先上目录 目录 问题简介 基础模型、扩展问题及应用 算法 参考文献 1 问题简介 为了更好地了解这个问题&#xff0c;我们不妨当一波老板。 想象一下我们是经营一家口罩生产企业的老板&am…

案例——数据表的基本操作

目录 案例目的&#xff1a; 创建表&#xff1a; 创建offices&#xff1a; 创建employees表&#xff1a; 修改表&#xff1a; 将 employees 的 mobile 字段移动到 officeCode 字段后&#xff1a; 将 birth 字段名称改为 employee_birth: 修改 sex 字段&#xff0c;数据类…

Vue的路由实现:hash模式 和 history模式原理及区别

目录标题 1、hash模式2、history模式 Vue-Router有两种模式: ** hash 模式和 history**模式。默认的路由模式是hash模式。 1、hash模式 简介&#xff1a;hash模式是开发中默认的模式&#xff0c;它的URL带着一个#&#xff0c;例如:http://www.abc.com/#/vue&#xff0c;它的…

Facebook、Google、亚马逊,谁将成为跨境电商的营销宠儿?

跨境电商在全球范围内的发展日益迅猛&#xff0c;而营销渠道的选择也变得越来越多样化。在众多的广告平台中&#xff0c;Facebook、Google和亚马逊被公认为是跨境电商卖家们最主要的营销平台。那么&#xff0c;这三个平台中哪个会成为跨境电商的营销宠儿呢&#xff1f; 一、Fac…

【GIT】git push后长时间没反应

方向一 查看是否添加ssh 打开git bash cd ~/.ssh看是否成功&#xff0c;能成功说明之前生成过&#xff0c;看文件夹下是否有id_rsa.pub和id_rsa文件&#xff0c;有的话跳过生成步骤3 输入 ssh-keygen -t rsa -C ‘your_emailexample.com’(注&#xff1a;your_emailexample.c…

二百左右的蓝牙耳机哪款好?200左右音质最好的蓝牙耳机

在日常生活中离不开智能手机&#xff0c;特别是对无线蓝牙耳机的需求程度也越来越高&#xff0c;但是市面上有很多的蓝牙耳机戴久了耳朵会出现不舒服&#xff0c;为了获得更好的使用体验&#xff0c;我整理了市面上200左右价位佩戴和音质都表现不错的蓝牙耳机。 一、南卡小音舱…

“SCSA-T学习导图+”系列:IPSec VPN原理与应用

本期引言&#xff1a; 本章主要讲解IPSec VPN相关理论概念&#xff0c;工作原理。从安全和加密原理入手&#xff0c;讲解了IPSec 在VPN对等体设备实现的安全特性&#xff0c;如数据的机密性、数据的完整性&#xff0c;数据验证等。重点分析IPSec封装模式&#xff0c;IPSec安全…

【HDCTF2023】wp

【HDCTF2023】wp 文章目录 【HDCTF2023】wpwebWelcome To HDCTF 2023SearchMasterYamiYamiLoginMaster mischardMiscMasterMiscExtremeMiscSuperMisc web Welcome To HDCTF 2023 在源码的 game.js中找到了flag 在控制台输出 console.log(seeeeeeeecret)得flag SearchMaster …