在 TypeScript 中,接口(interface)不仅可以描述对象的结构,还可以通过 extends 实现接口继承,用于复用公共字段、规范数据模型结构,是中大型项目中非常常见的用法。
一、什么是接口继承?
接口继承指的是:
一个接口在已有接口的基础上,继承其所有属性,并在此之上进行扩展。
语法形式:
interface Child extends Parent {
// 新增或扩展的属性
}
继承后,Child 会自动包含 Parent 中定义的全部属性。
二、为什么要使用接口继承?
如果多个数据结构中存在重复字段,直接在每个接口中重复定义,会带来以下问题:
字段重复,代码冗余
修改公共字段成本高
可维护性和一致性差
接口继承的核心目的就是:
抽取公共结构,减少重复,提高可维护性。
三、基础示例
1. 定义基础接口
interface BaseElement {
id: string;
type: string;
}
该接口用于描述所有元素都具备的公共属性。
2. 通过 extends 扩展
interface LineElementData extends BaseElement {
type: "line";
startX: number;
startY: number;
endX: number;
}
interface RectElementData extends BaseElement {
type: "rect";
x: number;
y: number;
width: number;
height: number;
}
此时:
LineElementData=BaseElement+ 线条自身属性RectElementData=BaseElement+ 矩形自身属性
四、接口继承的本质
interface LineElementData extends BaseElement {
startX: number;
}
等价于:
interface LineElementData {
id: string;
type: string;
startX: number;
}
接口继承并不是代码拷贝,而是类型结构的合并。
五、接口继承的常见使用场景
1. 统一处理不同子类型
function renderElement(el: BaseElement) {
console.log(el.id, el.type);
}
LineElementData、RectElementData 等子接口都可以作为参数传入。
子接口可以被当作父接口使用(结构兼容性)。
2. 配合联合类型进行类型区分
type ElementData = LineElementData | RectElementData;
function draw(el: ElementData) {
if (el.type === "line") {
el.startX;
}
if (el.type === "rect") {
el.width;
}
}
这是 Canvas、图形编辑器、流程图等项目中的高频模式。
3. 多接口继承
interface Selectable {
selected: boolean;
}
interface LineElementData extends BaseElement, Selectable {
startX: number;
startY: number;
endX: number;
}
一个接口可以同时继承多个接口,用于组合不同能力。
六、interface 继承 vs class 继承
interface 是类型约束,class 是具体实现。
七、使用建议(实践经验)
公共字段应优先抽到基础接口
type字段建议使用字面量类型,便于类型收窄数据模型复杂时,接口继承比重复定义更清晰
interface 更适合描述“数据结构”,而非业务逻辑
八、总结
extends用于在已有接口的基础上进行扩展子接口会自动拥有父接口的所有属性
接口继承是构建清晰、可维护类型系统的重要手段