在type="module"脚本中可向window挂载变量,但需确保执行时机可控、类型可识别,并通过global.d.ts声明ts类型,避免非模块脚本提前访问或隐式声明。

在 type="module" 脚本中向 window 挂载变量是可行的,但必须明确:模块本身不自动污染全局,挂载动作是开发者主动行为,关键在于“时机可控”和“类型可识别”。否则容易出现运行时访问不到、TS 类型报错、或被其他脚本覆盖等问题。
确保挂载发生在模块执行完成之后
模块脚本默认 defer,即 DOM 解析完、所有依赖就绪后才执行。普通 <script></script> 会更早运行,若此时尝试读取 window.xxx,必然为 undefined。
- ✅ 正确做法:所有使用该全局变量的代码,也必须放在
type="module"中,或监听模块就绪信号 - ✅ 推荐统一用模块化方式组织,避免混合加载带来的时序混乱
- ⚠️ 避免在非模块脚本中直接调用
window.xxx(),除非你已用事件或 Promise 显式同步
挂载写法要简洁明确
直接赋值即可,无需绕弯:
完整的Galileo AI平台 TypeScript/JS SDK 参考,用于评估、观察和保护 GenAI 应用。适用于构建 Node.js 或 TypeScript 项目。
window.myApi = { fetchUser, saveConfig };window.VERSION = "2.1.0";- 不要用
var或隐式声明(如myTool = {}),这在模块内会报错(严格模式) - 避免
eval、with或this === window的旧式写法,它们可能绕过作用域隔离
TypeScript 中让类型系统认可挂载
仅运行时挂载还不够,TS 编译器需要知道 window 上多了这个属性,否则会提示“Property 'xxx' does not exist on type 'Window'”。
- 新建一个
global.d.ts文件(或已有声明文件),加入:
myApi: { fetchUser: (id: string) => Promise
VERSION: string;
}
- 文件末尾必须有
export {};,否则 TS 不认为它是模块,无法触发全局声明合并 - 不要在 .ts 文件里写
declare global后直接赋值——类型声明和运行时赋值要分离
验证是否真正安全挂载
打开控制台,运行这几行快速排查:
-
console.log(window.myApi)—— 看是否为预期对象 -
Object.getOwnPropertyDescriptor(window, 'myApi')—— 检查configurable是否为true(正常挂载应为true) -
Object.keys(window).includes('myApi')—— 确认它确实出现在window枚举列表中










