面试题答案
一键面试定义方式
- 交叉类型:使用
&
运算符将多个类型合并为一个类型,新类型同时拥有所有参与交叉类型的特性。例如:type NewType = Type1 & Type2;
- 类型别名:使用
type
关键字来为一个类型定义别名。可以是基本类型、联合类型、自定义类型等。例如:type Alias = string | number;
或type User = { name: string; age: number; };
使用场景
- 交叉类型:
- 常用于组合多个对象类型,创建一个具有多个对象类型所有属性的新类型。比如,有一个
BasicInfo
类型和ContactInfo
类型,想要一个同时包含两者信息的类型时使用交叉类型。 - 也用于合并一些具有不同行为或属性集合的类型,以满足特定的复杂需求。
- 常用于组合多个对象类型,创建一个具有多个对象类型所有属性的新类型。比如,有一个
- 类型别名:
- 主要用于简化复杂类型的引用。例如当一个联合类型非常复杂时,使用类型别名可以让代码更易读。
- 还可用于给已有的类型创建一个更具描述性的名字,方便代码维护和理解。
特性
- 交叉类型:
- 合并属性:若交叉的类型中有同名属性,属性类型必须兼容(如果是对象类型,同名属性类型需相同或满足子类型关系)。例如
{ a: string } & { a: number }
会报错,因为string
和number
不兼容。 - 特性叠加:新类型拥有所有交叉类型的特性,会按照顺序依次应用各类型的特性。
- 合并属性:若交叉的类型中有同名属性,属性类型必须兼容(如果是对象类型,同名属性类型需相同或满足子类型关系)。例如
- 类型别名:
- 仅是一个别名,不会创建新类型,本质上和原类型是同一个类型。例如
type MyString = string;
,MyString
和string
是一样的。 - 可以用于递归定义类型,比如定义链表类型。
- 仅是一个别名,不会创建新类型,本质上和原类型是同一个类型。例如
代码示例
// 交叉类型示例
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 };
通过上述代码可以看到,交叉类型用于合并不同类型的特性,而类型别名主要用于简化复杂类型引用或给已有类型取更具描述性的名字,在递归定义类型方面也有独特应用。