声明合并是 TypeScript 将多个具有相同名称的声明合并为单一定义。接口、命名空间和某些其他构造会自动合并。
接口合并
ts
interface Box { width: number; }
interface Box { height: number; }
// Box is now { width: number; height: number } — both merged
杀手级用例:增强第三方/全局类型
这是如何为你不拥有的库或全局变量添加类型的方式:
// Add a custom property to Express's Request
declare global {
namespace Express {
interface Request { user?: { id: string }; } // merges into Express.Request
}
}
request.user; // ✅ now typed everywhere
// Augment a module
declare module "some-lib" {
interface Options { newOption: boolean; }
}
由于库的 Request/Options 是一个 interface,你的声明会合并到其中,而不是产生冲突 — 让你能够安全地扩展你无法编辑的类型。
function greet() {}
namespace greet { export const version = "1.0"; }
greet.version; // "1.0" — namespace merged onto the function
type 不能做到这一点type A = { x: number };
type A = { y: number }; // ❌ Error: duplicate identifier
类型别名是唯一的;只有接口(和命名空间)会合并 — 这是对可扩展公共 API 形状使用 interface 的关键原因。
声明合并是模块扩展背后的机制 — 扩展 Express 请求、添加到 window、自定义库类型、主题系统。
这是在实际应用中编写类型的必要知识,你需要适配你无法控制的类型,而无需分叉它们。