面试题答案
一键面试交叉类型(Intersection Types)和联合类型(Union Types)的区别
-
定义
- 交叉类型:用
&
符号表示,它将多个类型合并为一个类型。新类型同时具备所有参与交叉类型的特性。例如type A = { name: string }; type B = { age: number }; type AB = A & B;
,AB
类型的对象需要同时拥有name
(字符串类型)和age
(数字类型)属性。 - 联合类型:用
|
符号表示,它表示一个值可以是几种类型之一。例如type C = string | number;
,变量声明为C
类型时,它的值可以是字符串或者数字。
- 交叉类型:用
-
实际场景使用
- 交叉类型实际场景:比如在开发一个用户管理系统,可能有普通用户类型
User
和管理员用户类型Admin
。有时会有超级管理员,他既具备普通用户的属性,又有管理员的属性。
- 交叉类型实际场景:比如在开发一个用户管理系统,可能有普通用户类型
type User = {
name: string;
email: string;
};
type Admin = {
role: string;
permissions: string[];
};
type SuperAdmin = User & Admin;
let superAdmin: SuperAdmin = {
name: 'John Doe',
email: 'johndoe@example.com',
role: 'Super Admin',
permissions: ['all']
};
- **联合类型实际场景**:在一个图形绘制函数中,可能接受圆形或者矩形作为参数。
type Circle = {
type: 'circle';
radius: number;
};
type Rectangle = {
type:'rectangle';
width: number;
height: number;
};
type Shape = Circle | Rectangle;
function draw(shape: Shape) {
if (shape.type === 'circle') {
console.log(`Drawing a circle with radius ${shape.radius}`);
} else {
console.log(`Drawing a rectangle with width ${shape.width} and height ${shape.height}`);
}
}
let circle: Circle = { type: 'circle', radius: 5 };
let rectangle: Rectangle = { type:'rectangle', width: 10, height: 5 };
draw(circle);
draw(rectangle);
联合类型中多个类型时的类型推断
当联合类型中包含多个类型时,TypeScript 会进行如下类型推断:
- 属性访问:如果访问联合类型的属性,只有所有类型都有的属性才能被安全访问。例如
type D = { a: string } | { b: number }; let d: D; console.log(d.a); // 报错,因为不是所有类型都有 'a' 属性
。 - 函数调用:当调用联合类型的值的函数时,只有所有类型都有的函数才能被调用。
- 类型保护:通过类型保护(如
typeof
、instanceof
或者自定义类型保护函数)来缩小联合类型的范围,以便访问特定类型的属性或方法。例如在上述draw
函数中,通过if (shape.type === 'circle')
来判断shape
是Circle
类型,从而可以安全访问radius
属性。