MST

星途 面试题库

面试题:TypeScript交叉类型与类型别名的深度对比

详细阐述TypeScript交叉类型与类型别名在定义方式、使用场景、特性等方面的区别,并通过复杂的代码示例来展示两者的不同之处。
25.5万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

定义方式

  • 交叉类型:使用 & 运算符将多个类型合并为一个类型,新类型同时拥有所有参与交叉类型的特性。例如:type NewType = Type1 & Type2;
  • 类型别名:使用 type 关键字来为一个类型定义别名。可以是基本类型、联合类型、自定义类型等。例如:type Alias = string | number;type User = { name: string; age: number; };

使用场景

  • 交叉类型
    • 常用于组合多个对象类型,创建一个具有多个对象类型所有属性的新类型。比如,有一个 BasicInfo 类型和 ContactInfo 类型,想要一个同时包含两者信息的类型时使用交叉类型。
    • 也用于合并一些具有不同行为或属性集合的类型,以满足特定的复杂需求。
  • 类型别名
    • 主要用于简化复杂类型的引用。例如当一个联合类型非常复杂时,使用类型别名可以让代码更易读。
    • 还可用于给已有的类型创建一个更具描述性的名字,方便代码维护和理解。

特性

  • 交叉类型
    • 合并属性:若交叉的类型中有同名属性,属性类型必须兼容(如果是对象类型,同名属性类型需相同或满足子类型关系)。例如 { a: string } & { a: number } 会报错,因为 stringnumber 不兼容。
    • 特性叠加:新类型拥有所有交叉类型的特性,会按照顺序依次应用各类型的特性。
  • 类型别名
    • 仅是一个别名,不会创建新类型,本质上和原类型是同一个类型。例如 type MyString = string;MyStringstring 是一样的。
    • 可以用于递归定义类型,比如定义链表类型。

代码示例

// 交叉类型示例
interface BasicInfo {
  name: string;
}
interface ContactInfo {
  phone: string;
}
// 交叉类型创建新类型
type FullInfo = BasicInfo & ContactInfo;
let person: FullInfo = { name: 'John', phone: '1234567890' };

// 类型别名示例
// 定义复杂联合类型的别名
type ComplexValueType = string | number | boolean | null | undefined;
function printValue(value: ComplexValueType) {
  console.log(value);
}
printValue('hello');
printValue(123);

// 类型别名递归示例
type ListNode = {
  value: number;
  next: ListNode | null;
};
let head: ListNode = { value: 1, next: null };
let newNode: ListNode = { value: 2, next: head };

通过上述代码可以看到,交叉类型用于合并不同类型的特性,而类型别名主要用于简化复杂类型引用或给已有类型取更具描述性的名字,在递归定义类型方面也有独特应用。