在 TypeScript 中,interface 和 type 都可以用来定义对象的形状,但它们有一些关键的区别和各自的适用场景。以下是两者的区别和使用场景:
区别
- 声明合并 (Declaration Merging):
interface可以声明多次,并且会自动合并。type则不支持声明合并。
interface User { name: string; } interface User { age: number; } const user: User = { name: 'Alice', age: 25, }; // 合法,User 接口自动合并type User = { name: string; }; type User = { age: number; }; // 错误,类型别名不能重复声明 - 扩展性:
interface支持使用extends进行扩展。type可以使用交叉类型(&)进行组合。
interface Person { name: string; } interface Employee extends Person { employeeId: number; } const employee: Employee = { name: 'Alice', employeeId: 123, }; // 合法type Person = { name: string; }; type Employee = Person & { employeeId: number; }; const employee: Employee = { name: 'Alice', employeeId: 123, }; // 合法 - 复杂类型:
type可以定义更复杂的类型,包括联合类型、元组、映射类型等。interface主要用于定义对象类型。
type StringOrNumber = string | number; type Tuple = [string, number]; type Dictionary<T> = { [key: string]: T; };
使用场景
- 使用
interface的场景:- 需要利用声明合并。
- 需要通过
extends继承其他接口。 - 定义对象的形状,尤其是在公开 API 时。
- 使用
type的场景:- 需要定义复杂类型(如联合类型、交叉类型、元组等)。
- 不需要声明合并。
- 更注重类型的灵活性和简洁性。
示例
使用 interface
interface Person {
name: string;
age: number;
}
interface Employee extends Person {
employeeId: number;
}
const employee: Employee = {
name: 'Alice',
age: 25,
employeeId: 123,
};
使用 type
type StringOrNumber = string | number;
type Person = {
name: string;
age: number;
};
type Employee = Person & {
employeeId: number;
};
const employee: Employee = {
name: 'Alice',
age: 25,
employeeId: 123,
};
type Tuple = [string, number];
const tuple: Tuple = ['Alice', 25];
type Dictionary<T> = {
[key: string]: T;
};
const dictionary: Dictionary<number> = {
apples: 10,
oranges: 20,
};
总结来说,如果你需要更强的扩展性和声明合并功能,interface 是更好的选择;如果你需要定义复杂类型并注重类型的灵活性,type 会更适合。