& 运算符将多个类型合并成一个新类型。下面是几种常见的实现示例:
interface Person {
name: string;
age: number;
}
interface Employee {
company: string;
id: number;
}
// 交叉类型:同时具有 Person 和 Employee 的属性
type EmployeePerson = Person & Employee;
const john: EmployeePerson = {
name: "John",
age: 30,
company: "Tech Corp",
id: 1001
};
// 缺少任何属性都会报错
const invalid: EmployeePerson = {
name: "Alice",
age: 25
// 错误:缺少 company 和 id 属性
};
interface Logger {
log(message: string): void;
}
interface Formatter {
format(data: any): string;
}
// 交叉类型:同时具有两个接口的方法
type LoggerFormatter = Logger & Formatter;
const loggerFormatter: LoggerFormatter = {
log(message: string) {
console.log(message);
},
format(data: any): string {
return JSON.stringify(data);
}
};
type Admin = {
adminLevel: number;
permissions: string[];
};
type User = {
id: string;
email: string;
};
// 交叉类型创建管理员用户
type AdminUser = User & Admin;
const admin: AdminUser = {
id: "user-123",
email: "admin@example.com",
adminLevel: 3,
permissions: ["read", "write", "delete"]
};
function merge<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
const obj1 = { name: "Alice" };
const obj2 = { age: 30 };
const merged = merge(obj1, obj2); // 类型为 { name: string } & { age: number }
console.log(merged.name); // "Alice"
console.log(merged.age); // 30
interface A {
value: number;
common: string;
}
interface B {
value: string; // 与 A 的 value 类型冲突
common: string;
}
// 冲突的属性会变成 never 类型
type Conflict = A & B;
// 以下代码会报错,因为 value 的类型是 never
const obj: Conflict = {
value: "test", // 错误:不能将 string 赋值给 never
common: "hello"
};
// 1. 构建复杂组件 Props
interface BaseProps {
className?: string;
id?: string;
}
interface ButtonProps {
onClick: () => void;
disabled?: boolean;
}
type ComponentProps = BaseProps & ButtonProps;
// 2. Mixin 模式
class Disposable {
isDisposed: boolean = false;
dispose() {
this.isDisposed = true;
}
}
class Activatable {
isActive: boolean = false;
activate() {
this.isActive = true;
}
deactivate() {
this.isActive = false;
}
}
// 使用交叉类型表示合并后的类型
type SmartObject = Disposable & Activatable;
function createSmartObject(): SmartObject {
// 创建对象并组合两个类的功能
return Object.assign(
{},
new Disposable(),
new Activatable()
);
}
const smartObj = createSmartObject();
smartObj.activate();
smartObj.dispose();
// 过滤掉某些属性
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
// 确保两个类型互斥
type XOR<T, U> = (T | U) extends object
? (Without<T, U> & U) | (Without<U, T> & T)
: T | U;
// 使用示例:要么有 a,要么有 b,但不能同时有
type Options = XOR<{ a: string }, { b: number }>;
const opt1: Options = { a: "test" }; // ✓
const opt2: Options = { b: 123 }; // ✓
const opt3: Options = { a: "test", b: 123 }; // ✗ 错误
never 类型
类型推断:交叉类型的推断是深度合并,不仅仅是浅层合并
编译时特性:交叉类型只在编译时存在,运行时没有对应的 JavaScript 代码
性能考虑:过度复杂的交叉类型可能会影响编译性能
交叉类型在构建复杂的类型系统、实现 Mixin 模式、以及组合多个类型约束时非常有用。