
在 TypeScript 中,interface 和 type 是用于定义类型结构的两种不同方式。尽管它们在很多情况下可以互换使用,但它们之间还是存在一些重要的区别和各自的适用场景。以下是它们的主要区别:
- 继承与合并
Interface: 可以使用 extends 关键字来继承另一个 interface,并且可以自动合并多个 interface 定义。 typescript复制代码interface Animal { name: string;} interface Dog extends Animal { breed: string;} const d: Dog = { name: 'Buddy', breed: 'Golden Retriever' }; 如果有多个具有相同名称的接口,它们会合并在一起: typescript复制代码interface User { id: number;} interface User { name: string;} const user: User = { id: 1, name: 'Alice' };
Type: 可以使用 & 交叉类型来组合多个 type,但不能直接继承。对于多个 type 的合并,需要使用交叉类型(Intersection Types)。 typescript复制代码type Animal = { name: string;}; type Dog = Animal & { breed: string;}; const d: Dog = { name: 'Buddy', breed: 'Golden Retriever' }; 对于多个 type 的合并: typescript复制代码type UserId = { id: number;}; type UserName = { name: string;}; type User = UserId & UserName; const user: User = { id: 1, name: 'Alice' };
- 可索引的类型
Interface: 可以定义可索引的类型,这对于描述对象具有动态键的情况非常有用。 typescript复制代码interface StringIndexedArray { [index: string]: number;} const myArray: StringIndexedArray = { 'a': 1, 'b': 2 };
Type: 不能直接定义可索引的类型,但可以通过映射类型(Mapped Types)来实现类似的功能。 typescript复制代码type StringIndexedArray = { [index in string]: number;}; const myArray: StringIndexedArray = { 'a': 1, 'b': 2 };
- 联合类型与交叉类型的定义
Interface: 不能直接定义联合类型或交叉类型,需要通过 type 来实现。 typescript复制代码type Admin = { name: string; privileges: string[];}; type User = { name: string; dateOfBirth: Date;}; type ElevatedUser = Admin & User; const user: ElevatedUser = { name: 'Alice', privileges: ['create-server'], dateOfBirth: new Date()};
Type: 可以直接定义联合类型和交叉类型。 typescript复制代码type Admin = { name: string; privileges: string[];}; type User = { name: string; dateOfBirth: Date;}; type ElevatedUser = Admin & User;type UserOrAdmin = Admin | User; const user: ElevatedUser = { name: 'Alice', privileges: ['create-server'], dateOfBirth: new Date()}; const adminOrUser: UserOrAdmin = { name: 'Bob', privileges: ['read-server'] };
- 函数类型定义
Interface: 可以用来定义对象字面量中包含的函数类型。 typescript复制代码interface SearchFunc { (source: string, subString: string): boolean;} const mySearch: SearchFunc = function(source: string, subString: string) { return source.includes(subString);};
Type: 也可以用来定义函数类型,并且更加灵活。 typescript复制代码type SearchFunc = (source: string, subString: string) => boolean; const mySearch: SearchFunc = function(source: string, subString: string) { return source.includes(subString);};
总结
使用 interface 适用于定义对象结构,尤其是当需要继承或合并多个类型定义时。 使用 type 更加灵活,适用于定义联合类型、交叉类型、映射类型等复杂类型结构。
根据具体需求选择合适的工具,可以让你的 TypeScript 代码更加简洁和可读。
