【TypeScript】交叉类型联合类型(四)
【TypeScript】交叉类型&联合类型(四)

- 【TypeScript】交叉类型&联合类型(四)
- 一、简介
- 二、交叉类型
- 2.1 交叉类型使用的注意点
- 2.2 基本数据类型交叉
- 2.3 对象类型交叉
- 三、联合类型
- 四、类型缩减
一、简介
TypeScript 中的交叉类型和联合类型是用来组合多个类型的方式。
- 交叉类型
交叉类型(Intersection Types)使用&符号将多个类型组合在一起,表示同时具备这些类型的特性。 - 联合类型
联合类型(Union Types)使用|符号将多个类型组合在一起,表示可以是其中任意一个类型。
二、交叉类型
交叉类型, 简单来说就是通过&符号将多个类型进行合并成一个类型,然后用type来声明新生成的类型。
这里我举个例子,具体如下:
type A = { foo: number };
type B = { bar: string };
type C = A & B;const obj: C = { foo: 123, bar: "abc" };
在上面的例子中,类型 C 是类型 A 和类型 B 的交叉类型,表示同时具备 foo 和 bar 属性。变量 obj 符合交叉类型 C 的定义,拥有 foo 和 bar 属性。这就是一个典型的交叉类型。
2.1 交叉类型使用的注意点
在使用交叉类型时,有几个注意点需要考虑:
问:任何类型都能通过 & 合并成新的类型吗?
答:这肯定是 不行 的,原子类型进行合并是没有任何意义,因为它们合并后的类型是 never,比如 string & number,这肯定是错误的,因为不可能有既满足字符串又能满足数字类型的值.
type A = string & number; // 错误:基本类型无法进行交叉操作
问:交叉的类型中具有同名属性,该怎么处理?
答:这里分两种情况,如果同名属性的类型相同则合并后还是原本类型,如果类型不同,则合并后类型为never
- 合并后是string
type A = { foo: string };
type B = { foo: string };
type C = A & B; // 合并后是neverconst obj: C = { foo: "abc" }; // 使用类型断言解决冲突
- 合并后是never
type A = { foo: number };
type B = { foo: string };
type C = A & B; // 合并后是neverconst obj: C = { foo: "abc" }; // 报错, 可以使用这个避免错误 { foo: "abc" as never };

2.2 基本数据类型交叉
- any和number交叉结果是any类型
- any和boolean交叉结果是any类型
- any和string交叉结果是any类型
- any和never交叉结果是never类型。
注意:any 类型和除 never 类型以外的任何类型交叉时都为any
type A = any & 1; //any
type B = any & boolean; //any
type C = any & never; //neverlet Aname: A = 'lining'
let Bname: B = 'lining'
其他情况比较:
type A = number & 1; //1
type B = 'maoxiansheng' & string; //'maoxiansheng'
type C = boolean & true; //true
2.3 对象类型交叉
- 键的类型是对象类型
A、B、C三个类型都有相同的键inner,但是键的数据类型不同,分别是D、E、F,此时A&B&C会将inner键的类型进行合并,其实是D、E、F的交叉类型。
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}
};
- 键的类型是字面量类型或字面量联合类型
字面量类型是可辨识的类型,当键的类型是不同的字面量类型,则交叉后类型为never类型。type A = {kind:'a',loyal:number } type B = {kind:'b',loyal:string }type AB = A&B;//never - 函数类型的交叉运算
函数类型的交叉运算会使用ts中函数重载来实现。type A = (a:number,b:number) => void type B = (a:string,b:string) => void type AB = A&B;let func:AB = (a:number | string ,b:number | string) => {} func(1,2)//正常 func('a','b')//正常 func(1,'b')//报错
由于联合后,没有对应的func(number, string)类型的参数,因此会报出错误,解决上面的问题,只需要再加一个数据类型,其中 a为number类型,b为string类型。具体如下:type A = (a:number,b:number) => void type B = (a:string,b:string) => void type C = (a:number,b:string) => void type ABC = A&B&C;let func:ABC = (a:number | string ,b:number | string) => {} func(1,2)//正常 func('a','b')//正常 func(1,'b')//正常
相信小伙伴能够看懂这里的逻辑了吧,就是交叉的类型需要成对的匹配,那假如再出现需要传递的参数是func(string,number)类型的参数,有应该如何处理?只需要再添加新的类型即可:type C = (a:string,b:number) => void
但是,实际操作可能不需要这么麻烦,除非必要必须这样做。通常我们会有更加简单的方案直接定义。
三、联合类型
联合类型和交叉类型比较相似,联合类型通过 | 符号连接多个类型从而生成新的类型。
它主要是取多个类型的交集,即多个类型共有的类型才是联合类型最终的类型。联合类型可以是多个类型其中一个,可做选择,比如: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' }let value2:XY = {q:1,r:'r',w: 'w' }错误演示,多余 x 属性。
interface X{q:number,w:string,r:string} interface Y{q:numberr:string, } type XY = X | Y let value3:XY = {q:1,r:'r',x: 'x' // Error,Type '{ q: number; r: string; x: string; }' is not assignable to type 'XY'. } -
函数接口类型进行联合
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()
扩展:boolean 类型可以看成是 true | false 的联合类型
四、类型缩减
-
当字面量类型和原始类型进行联合,那么就会造成类型缩减。
type A = 'a' | string; //string类型 type B = false | boolean; //bolean 类型 type C = 1 | number; //number类型
如上,A是由字面量 a 和原始类型string组成,则会缩减为string类型。
- 枚举也会有类型缩减现象,如下:
enum Class{A,B} type C = Class.A | Class; //Class类型
注意⚠️:TS会把字面量类型和枚举成员类型给缩减掉,只剩下原始类型和枚举类型
当接口类型进行联合,接口中同名属性的类型不同,该怎么进行缩减呢?比如下面的例子
interface A{name:string
}
interface B{name:string | number[property:string]:any
}
type AB = A|B
会缩减为B类型,可以实际查看该运行结果
interface A{name:string
}
interface B{name:string | number[property:string]:any
}
type AB = A|Blet nameA: AB = { name: '' }
let nameB: AB = { name: 123 }
let nameC: AB = { name: 123, count: 256 }
以上就是TypeScript中交叉类型和联合类型的说明。感觉对自己有用的客观请不要吝啬你手中的三连,谢谢。
相关文章:
【TypeScript】交叉类型联合类型(四)
【TypeScript】交叉类型&联合类型(四) 【TypeScript】交叉类型&联合类型(四)一、简介二、交叉类型2.1 交叉类型使用的注意点2.2 基本数据类型交叉2.3 对象类型交叉 三、联合类型四、类型缩减 一、简介 TypeScript 中的交…...
数组和字符串-字符串
最长公共前缀 题意: 给多个字符串,找最长前缀 解: 暴力匹配,先按字典序排序字符串,这样长度短的优先进行匹配,所得字符串就可能偏小 适合a aa aaa aaaa这样的数据,不过对于aa aab aabc aab…...
MySQL-索引基础
文章概要 本篇文章通过几个问题来了解MySQL中索引相关的概念。平时在学习MySQL时或多或少都听说过索引的概念,但是索引到底是个什么东西,可能还不是非常的清楚。 正文 1. 什么是索引? 索引,在MySQL中也称为键(key),…...
CentOS中自动加载802.1q模块
CentOS中自动加载802.1q模块 要想在CentOS中自动加载内核模块,需要在/etc/sysconfig/modules/目录中增加一个脚本,在此脚本中加载所需的模块。 下面是我所用的一个名为8021q.modules的脚本,用来在我的CentOS 5.3中自动加载802.1Q模块&#…...
CSP-J2022第一轮试题
...
使用Java根据表名导出与导入Sql
前言 很粗糙啊,有很多可以优化的地方,而且也不安全,但是临时用还是OK的,我这个是公司里面的单机软件,不联网。 嗨!我是一名社交媒体增长黑客,很高兴能帮助您优化和丰富关于批量作业导出和导入…...
Elasticsearch同时使用should和must
问题及解决方法 must和should组合查询,should失效。使用must嵌套查询,将should组成的bool查询包含在其中一个must查询中。 SearchRequest request new SearchRequest(); request.indices("function_log");SearchSourceBuilder sourceBuilde…...
羽毛球热身和拉伸
1、绕场地慢跑 2、拉伸练习 拉伸动作主要有腕踝关节热身、下蹲、弓箭步压腿、后蹲压腿、腹背 具体动作可自行搜索练习 3、挥拍练习 杀球上网挥拍练习 正手挑球练习、反手挑球练习 4、拉伸 脚踝:一脚支持,另一脚拇指撑地正反向来回几圈转动脚踝&#…...
使用 Vue 实现页面访问拦截
使用 Vue 实现页面访问拦截 在现代的 Web 应用程序中,页面访问拦截是非常重要的一个方面。它可以用于确保用户只能访问他们有权限的页面,提高应用程序的安全性和用户体验。本篇博文将介绍如何使用 Vue 框架来实现页面访问拦截的功能。 文章目录 使用 Vu…...
使用webpack建立React+TS项目
之前写过类似的文章,这次看到一本新书里也介绍了这个知识点,故尝试之。 Refer: 《Learn React With TypeScript - A Beginners Guide To Reactive Web Development With React 18 and TypeScript》chapter3 Creating a project with webpack 1.先建立一…...
法律监督大数据平台有什么作用?
大数据赋能时代法律监督,构建法律行业领域大数据监督模型。法律监督大数据研判系统助力检察机关以社会公正为核心价值追求,对执法不严、司法不公“零容忍”,强化对诉讼活动的法律监督,坚决维护法律尊严,坚决捍卫公平正…...
根据制定的长度切割list值
88、根据制定的长度切割list值 依赖,谷歌开源的工具类库,非常的强大 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>29.0-jre</version> </dependency>其…...
AES加密(1):AES基础知识和计算过程
从产品代码的安全角度考虑,我们需要对代码、数据进行加密。加密的算法有很多种,基于速度考虑,我们一般使用对称加密算法,其中有一种常见的对称加密算法:AES(Advanced Encryption Standard)。在一些高端的MCU࿰…...
Nginx启动报错- Failed to start The nginx HTTP and reverse proxy server
根据日志,仍然出现 “bind() to 0.0.0.0:8888 failed (13: Permission denied)” 错误。这意味着 Nginx 仍然无法绑定到 8888 端口,即使使用 root 权限。 请执行以下操作来进一步排查问题: 确保没有其他进程占用 8888 端口:使用以…...
五、web应用程序技术——web功能
文章目录 一、服务器端功能1.1 SQL1.2 XML1.3 web服务 二、客户端功能2.1 HTML2.2 超链接2.3 表单2.4 CSS2.5 JavaScript2.6 文档对象模型2.7 Ajax2.8 JSON2.9 同源策略2.10浏览器拓展技术 一、服务器端功能 早期的web站点由各种静态资源组成,如HTML页面与图片。当用…...
AutoDL服务器的镜像版本太高,配置python3.7 tensorflow1.15版本的框架的步骤
1.选择一个实例,进入后端界面 2. 更新bashrc中的环境变量 conda init bash && source /root/.bashrc查看虚拟环境 conda info --envs可以看到此时有一个base的虚拟环境 但是它的python版本为3.8.10,无法安装tensorflow1.15,所以我们要创建一个…...
c++ boost库之scoped_ptr,shared_ptr,weak_ptr智能指针
头文件: #include <boost/smart_ptr.hpp> #include <boost/make_shared.hpp> #include <boost/shared_ptr.hpp> 1. scoped_ptr & scoped_array 只能在本作用域内使用,不希望被转让; 效率等同原始指针; scoped_ptr<string> sp(new string("t…...
【leetcode】383. 赎金信(easy)
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 class Solution {public boolea…...
CTF-记一次PWN练习
PWN是一个黑客语法的俚语词,自"own"这个字引申出来的,这个词的含意在于,玩家在整个游戏对战中处在胜利的优势,或是说明竞争对手处在完全惨败的情形下,这个词习惯上在网络游戏文化主要用于嘲笑竞争对手在整个…...
《golang设计模式》第一部分·创建型模式-04-工厂方法模式(Factory Method)
文章目录 1 概述2.1 角色2.2 类图 2 代码示例2. 1 设计2.2 代码2.3 类图 3. 简单工厂3.1 角色3.2 类图3.3 代码示例3.3.1 设计3.3.2 代码3.3.3 类图 1 概述 工厂方法类定义产品对象创建接口,但由子类实现具体产品对象的创建。 2.1 角色 Product(抽象产…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...
