TypeScript 中扩展全局类型须用无 export/import 的 .d.ts 文件,将 interface 扩展写在 declare global { } 内,如扩展 Window.Chart 或 Array.safeGet,仅声明类型不实现,运行时需单独补丁。

在 TypeScript 中,为挂载到全局对象(如 window、globalThis)的第三方 JS 库补充类型,最直接的方式是通过全局接口扩展——它不依赖 import,编译器自动识别,且能自然覆盖运行时已存在的行为。
必须用无 export 的 .d.ts 文件
扩展声明只能写在**没有 export 或 import 语句的 .d.ts 文件中**(例如 src/types/global.d.ts)。一旦文件含 export,TS 就将其视为模块作用域,declare global 将失效,扩展无法合并到全局环境。
- ✅ 正确:文件纯声明,无任何 export/import
- ❌ 错误:哪怕只有一行
export {};,整个declare global块就变成模块内声明,对window等无效
用 declare global 包裹接口扩展
所有要增强全局对象或内置类型的定义,必须放在 declare global { } 块内。不能直接写 interface Window { ... },否则 TS 报错“无法合并接口”。
- 扩展全局变量:如 CDN 引入的
Chart、$、mySDK - 扩展内置接口:如
Array、String、Date - 注意:只写类型,不写实现。例如给
Array加safeGet方法,仅声明签名,运行时需另行打补丁
常见扩展示例
比如通过 script 标签引入 Chart.js,它会挂载 window.Chart:
立即学习“Java免费学习笔记(深入)”;
declare global {
interface Window {
Chart: typeof import('chart.js');
}
}
再比如为所有数组添加安全取值能力:
declare global {
interface Array<T> {
safeGet(index: number): T | undefined;
}
}
对应运行时实现需单独写在 .ts 文件中,并确保被导入执行(如 polyfills/array-safe-get.ts)。
避坑要点
- 未声明的全局变量要先
declare const myLib: {...},不能只在 interface 里提它 - 多个
declare global块可共存,TS 自动合并同名接口(如都扩展Window) - 避免重写原生方法名(如
push、map),防止类型与运行时不一致 - 验证是否生效:在任意 .ts 文件中输入
window.,看编辑器是否提示你加的属性;或用tsc --noEmit检查报错


















