MST

星途 面试题库

面试题:TypeScript 中如何实现交叉类型与联合类型的应用

请解释 TypeScript 中交叉类型(Intersection Types)和联合类型(Union Types)的区别,并举例说明在实际场景中如何使用它们。同时,阐述当联合类型中包含多个类型时,TypeScript 是如何进行类型推断的。
20.4万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

交叉类型(Intersection Types)和联合类型(Union Types)的区别

  1. 定义

    • 交叉类型:用 & 符号表示,它将多个类型合并为一个类型。新类型同时具备所有参与交叉类型的特性。例如 type A = { name: string }; type B = { age: number }; type AB = A & B;AB 类型的对象需要同时拥有 name(字符串类型)和 age(数字类型)属性。
    • 联合类型:用 | 符号表示,它表示一个值可以是几种类型之一。例如 type C = string | number;,变量声明为 C 类型时,它的值可以是字符串或者数字。
  2. 实际场景使用

    • 交叉类型实际场景:比如在开发一个用户管理系统,可能有普通用户类型 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 会进行如下类型推断:

  1. 属性访问:如果访问联合类型的属性,只有所有类型都有的属性才能被安全访问。例如 type D = { a: string } | { b: number }; let d: D; console.log(d.a); // 报错,因为不是所有类型都有 'a' 属性
  2. 函数调用:当调用联合类型的值的函数时,只有所有类型都有的函数才能被调用。
  3. 类型保护:通过类型保护(如 typeofinstanceof 或者自定义类型保护函数)来缩小联合类型的范围,以便访问特定类型的属性或方法。例如在上述 draw 函数中,通过 if (shape.type === 'circle') 来判断 shapeCircle 类型,从而可以安全访问 radius 属性。