应将全局接口扩展写在无export的.d.ts文件中,用declare global包裹interface window等声明,确保编译器自动识别并合并类型,避免因模块化导致扩展失效。

在 TypeScript 中为第三方 JavaScript 库补充类型,最直接有效的方式之一是通过扩展全局接口(Global Interface Augmentation),尤其适用于挂载在全局对象(如 window、globalThis)上的库,或需要向内置类型(如 Array、String)添加方法的场景。
什么时候用全局接口扩展?
当 JS 库通过 <script></script> 引入、挂载到全局(比如 window.$、window.Chart),或你想增强原生类型(如给 Array.prototype 加方法)时,全局扩展比模块声明更自然。它不依赖导入路径,编译器自动识别,且无需修改原有模块结构。
如何正确扩展全局接口?
必须把声明写在**没有 export 的 .d.ts 文件中**(例如 src/types/global.d.ts),否则会被视为模块作用域,无法影响全局环境。
- 使用
declare global { ... }包裹要扩展的内容 - 内部可扩展全局变量、命名空间、或内置接口(如
Window、Array、String) - 不能在其中写实现代码,只写类型定义
例如,为通过 CDN 引入的 Chart.js 补全类型:
interface Window {
Chart: typeof import('chart.js');
}
}
扩展内置类型需谨慎
对 Array、Date 等内置对象扩展,应仅限通用、无副作用的方法,并确保运行时已打补丁:
- 类型声明写在
global.d.ts里 - 对应方法实现放在单独的
.ts文件中(如polyfills/array-safe-get.ts)并主动导入 - 避免与已有 API 冲突(如不要重写
map或push)
示例:为数组添加安全取值方法
declare global {interface Array
safeGet(index: number): T | undefined;
}
}
常见错误和避坑点
- 文件里写了
export—— 会导致声明被限制在模块内,全局扩展失效 - 直接写
interface Window { ... }(没包在declare global里)—— TypeScript 会报错“无法合并接口” - 试图扩展未声明的全局变量(如
myLib)却不声明其存在 —— 需配合declare const myLib: ... - 多个
declare global块是允许的,它们会自动合并,但接口名必须一致
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











