第4章:对象与接口
4.4 扩展接口(继承)
概述
接口的扩展(继承)是 TypeScript 中实现代码复用和类型层次结构的重要特性。通过继承,一个接口可以拥有另一个接口的所有成员,并在此基础上添加新的成员或覆盖现有成员。
基本语法
使用 extends 关键字实现接口继承:
interface Base {
id: number;
name: string;
}
interface Extended extends Base {
email: string;
age?: number; // 可选属性
}
多重继承
TypeScript 支持一个接口同时继承多个接口:
interface Printable {
print(): void;
}
interface Loggable {
log(): void;
}
interface Advanced extends Printable, Loggable {
timestamp: Date;
}
继承规则
属性覆盖:子接口可以声明与父接口同名的属性,但类型必须兼容
interface Base { status: string | number; } interface Derived extends Base { status: string; // 合法:string 是 string | number 的子类型 }可选属性:子接口可以将必选属性变为可选,但不能反过来
interface Base { required: string; optional?: number; } interface ValidExtension extends Base { required?: string; // 合法 } interface InvalidExtension extends Base { optional: number; // 错误!不能将可选属性变为必选 }
实际应用场景
组件属性扩展(React/Vue):
interface BaseProps { className: string; style: React.CSSProperties; } interface ButtonProps extends BaseProps { onClick: () => void; disabled?: boolean; }API 响应类型:
interface ApiResponse { success: boolean; timestamp: string; } interface UserResponse extends ApiResponse { data: { id: string; name: string; }; }
与类型别名的区别
类型别名使用交叉类型(&)实现类似效果,但接口继承更直观且支持声明合并:
// 使用类型别名
type Base = { id: number };
type Extended = Base & { name: string };
// 使用接口继承
interface IBase { id: number }
interface IExtended extends IBase { name: string }
最佳实践
- 优先使用接口继承而非类型交叉,除非需要联合类型特性
- 保持继承层次扁平(建议不超过3层)
- 考虑使用组合模式替代深层继承
常见问题
Q:接口能继承类型别名吗?
A:可以,只要类型别名是对象类型:
type BaseType = { id: number };
interface ExtendedInterface extends BaseType { name: string }
Q:循环继承是否允许?
A:TypeScript 会检测并报错:
// 错误示例
interface A extends B {}
interface B extends A {} // Error: 循环引用
