TypeScript 中的声明合并
说明 TypeScript 声明合并的基本机制、常见场景、风险点,以及为什么它既强大又容易被滥用。
#tech / dev
#resource / typescript
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: TypeScript MOC
- 总览页: TypeScript
- 并列概念: TypeScript 中的全局声明与全局扩展
- 相关调试: TypeScript 中 no-unsafe-declaration-merging 报错排查
TypeScript 中的声明合并
一句话定义
声明合并是 TypeScript 允许“同名声明在类型层面被合并”的机制,它常用于扩展接口、命名空间和部分现有类型,但也容易让边界变得隐式。
核心机制 / 工作原理
当多个声明使用同一个名字时,TypeScript 会在某些规则允许的前提下,把它们视为一个更大的类型定义。
最常见的几类包括:
- interface + interface
- namespace + class / function / enum
- 全局接口扩展
最小例子 / 最小场景
interface 合并
interface User {
id: string;
}
interface User {
name: string;
}
最终 User 同时拥有 id 和 name。
全局接口扩展
declare global {
interface Window {
appConfig: {
apiUrl: string;
};
}
}
这本质上也是声明合并的一种常见应用。
常见用途
- 扩展浏览器全局对象
- 给第三方库做类型补充
- 把多个分散声明汇总成统一类型
边界与易混淆点
能合并不代表就应该合并
声明合并的优势是灵活,代价是边界更隐式。阅读代码时,类型可能分散在多个文件里,不如显式导出那样直观。
类和接口的同名合并风险更高
这类写法虽然能增强类型提示,但也更容易让“运行时实现”和“类型补丁”脱节,所以很多团队会用 ESLint 限制它。
声明合并不是运行时混入
它主要发生在类型层面,不等于 JavaScript 运行时真的往对象上添加了实现。