尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TypeScript 中的类型合并与扩展:深入理解 interface 声明合并、继承与类型别名

TypeScript 中的类型合并与扩展:深入理解 interface 声明合并、继承与类型别名 文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载导读本篇文章聚焦《The Concise TypeScript Book》中「Mesclagem e Extensão」合并与扩展一章原文位置系统讲解 TypeScript 中两个极易混淆却又核心的概念声明合并Declaration Merging与类型扩展Type Extension。通过本文你将掌握 interface 同名多次声明为何会自动合并、extends关键字与交叉类型各自的适用场景、interface 与 type alias 在扩展能力上的边界差异并了解如何在类继承、命名空间等真实场景中组合运用这些机制写出结构清晰、可维护的类型代码。一、两个概念一条分界线合并与扩展的本质区别原文档开篇即给出定义合并merging与扩展extension是处理类型与接口时两个不同的概念。合并Merging允许把多个同名声明组合成一个单一定义。它发生在多个声明指向同一个名字的场景最典型的例子是重复定义同名interface。扩展Extension允许从已有类型或接口派生出新类型为既有类型追加额外的属性或方法而不修改原始定义。它发生在新类型以旧类型为基础的场景。一句话概括合并是把多个声明捏成一个名字扩展是从一个名字长出一个新名字。二者表面相似都会让最终类型拥有更多成员但语义与使用边界完全不同下面的章节逐一展开。二、声明合并同名 interface 的自动融合2.1 基础示例原文档给出的核心示例是重复声明同名interfaceinterface X { a: string; } interface X { b: number; } const person: X { a: a, b: 7, };这里连续两次声明了interface XTypeScript 会将二者合并为一个包含a: string与b: number的单一接口。因此person变量同时拥有两个属性编译期不会报错。2.2 为什么这样设计可扩展第三方类型声明合并的意义在于无需修改原始定义即可为其打补丁。这在以下场景中特别有用对应仓库文档 Diferenças entre Type e Interface 中的说明为来自第三方库或全局环境的类型追加自定义能力为缺失或错误的类型补充正确的成员在不改动依赖源码的前提下进行增量定制。2.3 注意type alias 不支持声明合并与 interface 相反type别名不支持声明合并。如果你写type A { x: string }; type A { y: string }; // ❌ 错误重复标识符 ATypeScript 会直接报重复标识符错误。这是 interface 与 type 之间最本质的能力差异之一interface 天生具备开放性open同名的声明会被合并type 则是闭合的同一作用域内一个名字只能定义一次。三、扩展从既有类型派生新类型3.1 interface 通过extends继承原文档的扩展示例interface Animal { name: string; eat(): void; } interface Bird extends Animal { sing(): void; } const dog: Bird { name: Bird 1, eat() { console.log(Comendo); }, sing() { console.log(Cantando); }, };Bird extends Animal意味着Bird继承了Animal的全部成员name与eat并新增自己的成员sing。最终Bird类型的对象必须同时满足两部分的约束。原文档特意强调扩展是一种在不修改原始定义的情况下为类型追加成员的机制——Animal本身没有任何变化只是派生了新的Bird。3.2 多接口继承一个 interface 可以同时扩展多个源对应 Estendendo Tipos 中的说明interface A { a: string; } interface B { b: string; } interface Y extends A, B { y: string; }此时Y同时拥有a、b、y三个成员。3.3 type 通过交叉类型扩展extends关键字只对 interface 与 class 生效对 type 别名扩展要通过交叉类型Intersection Type实现type A { a: number; }; type B { b: number; }; type C A B;交叉类型的语义是结果类型拥有所有参与交叉的类型的属性。这与接口继承的效果一致都是并集式地累积成员。交叉类型的通用定义与更多用法可参考仓库中的 Tipos de Interseção 一章。3.4 单向扩展规则interface 可以扩展 type反之不行TypeScript 允许用 interface 去扩展一个 type 别名但不允许用 type 去extends一个 interface因为 type 没有 extends 语法type A { a: string; }; interface B extends A { b: string; }上述代码合法B是一个 interface通过extends继承了类型别名A的a属性并新增b。反过来如果试图写type B ... extends ...语法上就不成立——type 侧只能用组合。3.5 一个关键限制interface 不能扩展联合类型由于联合类型union type的成员结构并不固定interface 的extends无法直接作用于它。这一限制在 Diferenças entre Type e Interface 中被明确提及interface 无法扩展一个复杂类型例如联合类型。遇到需要扩展联合类型的场景应使用 type 别名配合交叉或其他类型运算。四、interface 与 type 在合并/扩展能力上的完整对照将原文档与仓库中 Diferenças entre Type e Interface、Interface e Type 两章内容对照整理可以得出下面的能力矩阵能力interfacetype alias同名声明合并✅ 支持声明合并❌ 不支持重复声明报错继承/扩展其他 interface✅extends✅交叉继承/扩展 type 别名✅extends仅限可扩展的普通对象结构✅交叉扩展联合类型union❌ 无法直接 extends✅交叉与其他运算定义联合类型间接如type C A \| B其中 A、B 为 interface✅ 直接用\|定义交叉类型❌ 无内建支持✅ 直接用对应代码示例// type 擅长表达联合与交叉 type Department dep-x | dep-y; // 联合类型 type Person { name: string; age: number; }; type Employee { id: number; department: Department; }; type EmployeeInfo Person Employee; // 交叉类型 // interface 也可以作为联合类型的成员被组合 interface A { x: x; } interface B { y: y; } type C A | B; // 接口的联合由此可见需要开放性增量定制时优先 interface合并 extends需要表达联合、交叉或复杂类型运算时优先 type。两种工具各有所长实际项目中常常混用。五、合并与扩展在真实场景中的组合运用5.1 类的继承与接口实现扩展机制不仅作用于 interface也作用于 class。仓库 Classes 一章展示了类继承与多接口实现class Animal { name: string; constructor(name: string) { this.name name; } speak(): void { console.log(O animal faz um som); } } class Dog extends Animal { breed: string; constructor(name: string, breed: string) { super(name); this.breed breed; } speak(): void { console.log(Woof! Woof!); } }注意 TypeScript 与传统意义上的多继承不同一个类只能继承一个基类但可以同时实现多个接口interface Flyable { fly(): void; } interface Swimmable { swim(): void; } class FlyingFish implements Flyable, Swimmable { fly() { console.log(Voando...); } swim() { console.log(Nadando...); } }这与接口层面的extends A, B多源继承形成呼应类型层用继承 合并累积结构类层用单继承 多实现获得行为与契约。5.2 命名空间与接口的合并声明合并的另一常见形态是命名空间namespace与同名类的合并这在组织库的静态方法或类型时很实用相关语法见 Namespacingexport namespace MyNamespace { export interface MyInterface1 { prop1: boolean; } export interface MyInterface2 { prop2: string; } } const a: MyNamespace.MyInterface1 { prop1: true, };命名空间内的同名声明同样遵循合并规则可用于把类型与实现组织在统一命名空间下。5.3 常见的工程实践模式综合以上机制工程中经常出现的组合模式包括对第三方/全局类型做增量定制用同名 interface 重新声明自动合并补充新成员定义领域模型分层基础模型用 interface业务模型用extends派生保持基础定义不被污染组合多个关注点需要同时拥有多个来源的结构时用interface X extends A, B或type X A B联合类型驱动的灵活建模状态机、枚举集合等场景用type联合表达再配合交叉与其他类型运算衍生新类型。六、快速自检何时该用哪种方式你的需求推荐写法为已有 interface 追加成员不改原始定义再次声明同名 interface自动合并从一个 interface 派生新 interfaceinterface B extends A从多个 interface 派生新 interfaceinterface Y extends A, B从 type 别名派生新 interfaceinterface B extends AA 为 type从 type 组合出新 typetype C A B表达要么 A 要么 Btype C A \| B成员可为 interface扩展联合类型使用 type 与交叉/条件等类型运算结语合并与扩展是 TypeScript 类型系统中两条既平行又互补的增长路径合并让同名声明自动融合赋予类型开放性和增量定制的可能扩展让类型可以从既有定义派生新定义实现复用与分层。理解二者差异尤其是 interface 的声明合并、extends与的语法分工以及 type 在联合/交叉类型上的灵活性是写出高质量 TypeScript 类型设计的关键一步。本文涉及的核心章节与配套内容均可在仓库 pt-br 版本书籍目录 及其英文原版 book 目录 中继续深入阅读尤其是 Diferenças entre Type e Interface、Estendendo Tipos、Tipos de Interseção 与 Classes 各章。赞分享文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载相关推荐TypeScript 声明合并与类型扩展同名声明合并与接口继承的完整实战指南TypeScript 声明合并与类型扩展同名声明合并与接口继承的完整实战指南 导读 在 TypeScript 的类型系统中合并Merging与扩展文档教程TypeScript 接口合并与扩展Merging and Extension声明合并、继承与交叉类型完整指南TypeScript 接口合并与扩展Merging and Extension声明合并、继承与交叉类型完整指南 导读 在 TypeScript 的类型系统文档教程TypeScript 中 type 与 interface 的区别声明合并、扩展与联合/交叉类型实战指南TypeScript 中 type 与 interface 的区别声明合并、扩展与联合/交叉类型实战指南 本篇指南基于开源项目 The Concise Typ文档教程上一篇10分钟上手OPA Gatekeeper LibraryKustomize部署与约束配置最佳实践下一篇S905X3 盒子刷 Armbian从 0 到 1 点亮 3 个场景创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表