面试题答案
一键面试继承和扩展机制的不同
- 语法差异
- interface:使用
extends
关键字来实现继承。例如:
interface Animal { name: string; } interface Dog extends Animal { breed: string; }
- type:使用交叉类型
&
来实现类似继承的效果。例如:
type Animal = { name: string; }; type Dog = Animal & { breed: string; };
- interface:使用
- 重复属性处理
- interface:如果继承时出现重复属性,只要类型兼容就不会报错。例如:
interface A { prop: string; } interface B extends A { prop: string; // 不报错,只要类型相同 }
- type:使用交叉类型时,如果出现重复属性且类型不兼容会报错。例如:
type A = { prop: string }; type B = A & { prop: number }; // 报错,类型不兼容
- 功能特性
- interface:可以合并声明。例如:
interface User { name: string; } interface User { age: number; } // User接口现在有name和age属性
- type:不能合并声明,重新声明会报错。例如:
type User = { name: string; }; type User = { // 报错,重复声明 age: number; };
实际项目场景选择
- 对象类型明确且简单扩展时:如果项目中对象类型比较明确,并且扩展是简单的属性添加,
interface
是较好的选择。例如在一个简单的用户管理系统中,定义用户基础信息接口,然后扩展出管理员用户接口。interface User { id: number; name: string; } interface AdminUser extends User { role: 'admin'; }
- 复杂类型组合时:当需要将多个复杂类型组合在一起,
type
的交叉类型更灵活。比如在一个电商项目中,有商品基本信息类型和促销信息类型,需要组合出促销商品类型。type Product = { id: number; name: string; price: number; }; type Promotion = { discount: number; startDate: Date; }; type PromotionProduct = Product & Promotion;
- 需要合并声明时:如果项目中有需求在不同地方对同一类型进行补充声明,
interface
是唯一的选择。例如在一个大型应用的不同模块中,逐步完善用户相关的接口定义。// module1.ts interface User { name: string; } // module2.ts interface User { email: string; }
- 避免类型冲突时:如果担心重复属性导致类型冲突,使用
type
的交叉类型可以在编译阶段更早发现问题,适合对类型准确性要求较高的场景,比如底层库或者对数据格式严格要求的API接口定义。