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

news2024/10/5 15:35:03

【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; // 合并后是never

const obj: C = { foo: "abc" }; // 使用类型断言解决冲突
  • 合并后是never
type A = { foo: number };
type B = { foo: string };
type C = A & B; // 合并后是never

const 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; //never

let 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:number
    	r: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:number
    	r: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|B


let nameA: AB = { name: '' }
let nameB: AB = { name: 123 }
let nameC: AB = { name: 123, count: 256 }

以上就是TypeScript中交叉类型和联合类型的说明。感觉对自己有用的客观请不要吝啬你手中的三连,谢谢。






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

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

相关文章

【二】SPI IP核的使用

【一】SPI IP核使用:传送门 基于qsys通过spi外部总线协议对sd卡进行读写操作 一、实验平台与实验的目的: ​ 正点原子开拓者、芯片型号:EP4CE10F17C8;还需要一张sd卡。 ​ 该实验主要是利用SPI IP核驱动SD卡来实现读写实验&am…

主成分分析学习笔记

概述 主成分分析(Principal Component Analysis)是一种常见的数据分析方式,常用于高维数据的降维,提取数据的主要特征分量,其数学推导可以从最大可分性和最近重构性两个角度着手,前者的优化条件为划分后方…

MySQL-NoSQL整体笔记---持续输出中

MySQL部分 一、搭建 MySQL 数据库服务器 1、下载并上传glibc版本的Mysql 2、新建用户以安全方式运行进程 [roottemplate ~]# groupadd -r -g 306 mysql [roottemplate ~]# useradd -g 306 -r -u 306 mysql3、安装并初始化mysql [roottemplate ~]# tar xf mysql-5.7.36-linu…

【Azure Developer】使用 Microsoft Graph API 获取 AAD User 操作示例

问题解答 使用Microsoft Graph API,演示如何获取AAD User信息,因参考文档是针对Global Azure,所以文档种的URL为: // Global Azure Microsoft Graph API Host GET https://graph.microsoft.com/v1.0/me 需要修改为 // 中国区A…

iperf 安装与使用

iperf命令是一个网络性能测试工具,可以测试TCP和UDP带宽质量。同时也可以通过UDP测试报告网丢包率或者发包性能,是一个非常实用的工具 1.windwos安装 可以直接通过官网下载对应系统版本进行安装(https://iperf.fr/iperf-download.php&#…

无涯教程-Perl - each函数

描述 在列表context中调用此函数时,将返回一个由2个元素组成的列表,该列表由哈希的下一个元素的键和值组成,以便您可以对其进行迭代。在标量context中调用时,仅返回哈希中下一个元素的键。 语法 以下是此函数的简单语法- each HASH返回值 在列表context中调用此函数时,将返…

红帽认证前景如何,有什么优势?

红帽Linux认证优势: RedHat是全球最大的开源技术厂家,是世界领先的开源解决方案供应商,其产品RedHat Enterprise Linux(红帽企业级 Linux)也是全世界应用最广泛的Linux。 作为检验Linux技能的黄金标准, RHCE认证项目已…

农商行基于分类分级的数据安全管控建设实践

《数据安全法》颁布实施以来,以分类分级为基础,对数据进行差异化管理和防护,成为行业共识。 金融行业作为数据密集的高地,安全是重中之重,而鉴于金融数据种类和内容庞杂,面临规模化用数、普惠用数、跨机构共…

Selenium自动化测试之学会元素定位

这是我经常被问到的一个问题,也是我很讨厌回答的问题,因为要想回答这个问题需要知道上下文。什么样式的元素,有哪些属性,是否有表单嵌套,都尝试了哪些定位方法。。。而且没几个提问者能事先详细的说明这些。哪儿像提bu…

[Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序

1.今天开发了一套服务程序,使用的是Odbc连接MySql数据库, 在我本机用VS打开程序时,访问一切正常,当发布出来装在电脑上,连接数据库时提示: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定…

Python Opencv实践 - 基本图像IO操作

import numpy as np import cv2 as cv import matplotlib.pyplot as plt#读取图像 #cv2.IMREAD_COLOR: 读取彩色图像,忽略alpha通道,也可以直接写1 #cv2.IMREAD_GRAYSCALE: 读取灰度图,也可以直接写0 #cv2.IMREAD_UNCHANGED: 读取…

跨平台开发框架Qt:面向对象、丰富API

Qt是一个跨平台C图形用户界面应用程序开发框架,它具有以下三大优势: 优良的跨平台特性:Qt支持多种操作系统,包括Windows、Linux、Solaris、HP-UX、Irix、FreeBSD等,使开发人员能够在不同平台上开发和部署应用程序&…

如何在业务中体现TCC事务模型?

在分布式系统设计中,随着微服务的流行,通常一个业务操作被拆分为多个子任务,比如电商系统的下单和支付操作,就涉及到了创建和更新订单、扣减账户余额、扣减库存、发送物流消息等,那么在复杂业务开发中,如何…

【多重信号分类】超分辨率测向方法——依赖于将观测空间分解为噪声子空间和源/信号子空间的方法具有高分辨率(HR)并产生准确的估计(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

ApplicationContent 和BeanFactory的关系

选中这个类, ctrl alt u 从springboot的启动类说起 我们知道这个启动类返回值呢是哟个configurableApplicationContent 类型 我们查看她的类图 从图中我们可以看出,configurableApplicationContent是见解的继承了BeanFactory接口,扩展了他…

Centos7克隆快速复制多台虚拟机|互通互联

背景:有时候,我们在用虚拟机的时候会用到多个进行使用。重新安装会花费大量的时间,此时,我们可以通过vmware虚拟机自带的功能快速克隆出完全相同的系统。 前提:被克隆的虚拟机系统要处于关闭状态 步骤:…

elevation mapping学习笔记2之高程图输入、输出、服务和参数配置的定义和说明

文章目录 0 引言1 话题Topics1.1 订阅subscribe1.2 发布publish 2 服务Services3 参数Parameters 0 引言 elevation mapping学习笔记1已经成功编译安装elevation mapping高程图工程,并运行示例turtlesim3_waffle_demo,在仿真环境下,控制带有…

九、ESP32控制1602LCD屏幕显示内容

1. 运行效果 2. 1602简介 1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字) 市面上字符液晶大多数是基于HD44780液晶芯片的 需要8根数据线来传输要显示的数据,当然还

每天一道leetcode:剑指 Offer 04. 二维数组中的查找(中等二分查找)

今日份题目: 在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 示…

EP4CE6E22C8 FPGA最小系统电路原理图+PCB源文件

资料下载地址:EP4CE6E22C8 FPGA最小系统电路原理图PCB源文件 一、原理图 二、PCB