本文详解 TypeScript 中的交叉类型(Intersection)与联合类型(Union)。交叉类型使用 & 合并接口,同名属性类型不同时结果为 never;联合类型使用 | 表示多选一。文章还深入探讨了字面量与枚举联合导致的类型缩减现象,以及如何通过类型守卫处理联合类型中的属性访问问题。

交叉类型(Intersection types)
交叉类型是指通过 & 符号将多个类型合并为一个新类型,并使用 type 关键字来声明该新类型。例如:
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
}要点
是否任何类型都能通过 & 合并成新的类型?
- 并非如此。原子类型(如字符串和数字)的合并没有实际意义,因为合并后的类型是
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
}
};联合类型(Union types)
联合类型与交叉类型相似,它通过 | 符号连接多个类型以生成新类型。联合类型取多个类型的并集,即变量可以是其中任意一种类型。例如: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'
}- 对函数接口类型进行联合。
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()类型缩减
- 当字面量类型与原始类型进行联合时,会发生类型缩减。
type A = 'a' | string; //string类型
type B = false | boolean; //bolean 类型
type C = 1 | number; //number类型- 枚举同样存在类型缩减现象,如下所示:
enum Class{
A,
B
}
type C = Class.A | Class;//Class类型可以看出:TypeScript 会将字面量类型和枚举成员类型缩减,仅保留原始类型和枚举类型。 思考一个问题:当接口类型进行联合,且接口中同名属性的类型不同时,该如何进行缩减?例如以下情况,了解答案的朋友欢迎在评论区留言。
interface A{
name:string
}
interface B{
name:string | number
[property:string]:any
}
type AB = A|B本文关于 TypeScript 交叉类型和联合类型的介绍到此结束,更多相关 TS 交叉类型与联合类型内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!