typescript - 扩展全局属性
问题:
类型“Window & typeof globalThis”上不存在属性“my”
但是d.ts已经加了
declare global{
const my:string;
interface Window{ my:string }
}
不加 export {} 扩展不了window吗?
答案:
// global.d.ts(全局声明文件)
declare global {
const my: string;
interface Window {
my: string; // ❌ 这个扩展实际上不会生效!
}
}
// 没有 export {},这是一个全局声明文件
为什么需要
export {}?TypeScript 的模块识别规则
// 规则1:如果文件有 import/export → 是模块
// 规则2:如果文件没有 import/export → 是全局脚本// 全局脚本中的 declare global:
declare global {
// 这里的内容会被忽略!
// 因为全局脚本本身就在全局作用域,
// 不需要 declare global 包装
}// 模块中的 declare global:
declare global {
// 这里的内容会被添加到全局作用域
// 这是 declare global 的正确用法!
}
export {}; // 使文件成为模块四种情况的对比
情况1:全局文件,直接扩展 Window
// types/global.d.ts(没有 export)
interface Window {
my: string; // ✅ 有效,直接扩展
}
// 不需要 declare global
// 使用:window.my情况2:全局文件,使用 declare global
// types/global.d.ts(没有 export)
declare global {
interface Window {
my: string; // ❌ 无效!会被忽略
}
}
// 警告:在全局声明文件中不需要 declare global情况3:模块文件,扩展 Window
// types/window-extensions.d.ts
declare global {
interface Window {
my: string; // ✅ 有效
}
}
export {}; // ✅ 关键!使文件成为模块// 使用:window.my
情况4:模块文件,直接扩展 Window(错误)
// types/window-extensions.d.ts
interface Window {
my: string; // ❌ 错误!这是局部声明
}
export {}; // 文件是模块// 这里的 Window 接口是局部类型,
// 不会影响全局的 Window 接口
全局脚本世界(无 import/export)
// 文件:global-script.ts(或 .d.ts)
// 这里写的所有东西都自动在全局作用域const myGlobal = "hello"; // 自动全局
interface Window { // 自动扩展全局 Window
myProp: string;
}// 这里不需要 declare global,因为本来就在全局!
模块世界(有 import/export)
// 文件:module.ts
// 这里写的所有东西都只在模块内部const myLocal = "hello"; // 只在模块内可见
interface Window { // 创建的是局部 Window 类型,不影响全局
myProp: string; // 这不是扩展全局 Window!
}// 如果想影响全局,必须明确声明:
declare global {
interface Window { // ✅ 这会扩展到全局
myProp: string;
}
}
declare global的真实含义// 这句话的意思是:
"虽然我在一个模块里,但我要声明一些全局的东西"// 所以:
// 在模块中 + declare global = 声明全局内容 ✓
// 在全局中 + declare global = "我在全局中声明全局" ❌(冗余)
更多推荐



所有评论(0)