当前位置:首页 >> 编程语言 >> 【TypeScript】交叉类型联合类型(四),tcl idol x

【TypeScript】交叉类型联合类型(四),tcl idol x

cpugpu芯片开发光刻机 编程语言 1
文件名:【TypeScript】交叉类型联合类型(四),tcl idol x 【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; //anytype B = any & boolean; //anytype C = any & never; //neverlet Aname: A = 'lining'let Bname: B = 'lining'

其他情况比较:

type A = number & 1; //1type 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) => voidtype B = (a:string,b:string) => voidtype 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) => voidtype B = (a:string,b:string) => voidtype C = (a:number,b:string) => voidtype 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 | Ylet 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 | Ylet 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中交叉类型和联合类型的说明。感觉对自己有用的客观请不要吝啬你手中的三连,谢谢。


协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接