在 TypeScript 中,"interface"(接口)和 "type"(类型别名)是用来定义类型的两种方式。它们有一些共同点,也有一些区别,下面是它们的区别和用法:
- 定义语法:
- 接口(Interface):使用
interface
关键字来定义。 - 类型别名(Type Alias):使用
type
关键字来定义。 - 如:
// 接口定义 interface Person { name: string; age: number; } // 类型别名定义 type Person = { name: string; age: number; };
- 接口(Interface):使用
- 对象类型 vs 联合类型:
- 接口可以描述对象类型,可以定义对象的属性、方法和索引签名等。
- 类型别名可以描述对象类型,也可以描述联合类型、交叉类型和其他复杂类型。
- 如:
// 接口定义对象类型 interface Person { name: string; age: number; greet(): void; } // 类型别名定义联合类型 type ID = number | string;
- 同名合并:
- 接口可以通过同名合并来扩展定义,多个同名接口会自动合并成一个接口。
- 类型别名不能通过同名合并来扩展定义,如果重复定义同名的类型别名会报错。
- 如:
// 接口同名合并 interface Person { name: string; } interface Person { age: number; } // 合并后的接口 // interface Person { // name: string; // age: number; // } // 类型别名不能同名合并 type Person = { name: string; }; // 报错:重复定义了类型别名 'Person' type Person = { age: number; };
- 实现/继承:
- 接口可以被类实现(使用
implements
关键字)或者被其他接口继承。 - 类型别名无法直接实现或继承。
- 如:
// 接口实现和继承 interface Shape { getArea(): number; } class Circle implements Shape { radius: number; constructor(radius: number) { this.radius = radius; } getArea() { return Math.PI * this.radius * this.radius; } } // 类型别名不能实现或继承
- 接口可以被类实现(使用
总的来说,接口和类型别名在定义类型时有一些相似之处,但也存在一些区别。接口更常用于描述对象类型和进行面向对象的设计,而类型别名则更灵活,可以描述更复杂的类型,并与联合类型、交叉类型等结合使用。选择使用接口还是类型别名取决于具体的需求和代码组织方式。