TS中如何正确处理window类型

在Typescript项目中,你可能都遇到过这个错误:

'Window & typeof globalThis' 类型上不存在属性 'X'。

快速修复方案

我们将介绍几种不同的解决方案来解决这个问题。

Window 接口是在名为 lib.dom.d.ts 的文件中全局定义的。你可以使用各种技术来更改它:

  • 要在 .ts.tsx 文件中全局更改它,你可以使用 declare globalinterface Window
typescript 复制代码
declare global {
  interface Window {
    X: number;
  }
}
  • 要在 .d.ts 文件中全局更改它,你只需指定 interface Window
kotlin 复制代码
interface Window {
  X: number;
}
  • 要仅为一个文件更改它,你可以在 .ts.tsx 文件中使用 declare const window
sql 复制代码
declare const window: {
  X: number;
} & Window;

详细原因分析

Window 接口位于 TypeScript 的全局作用域中。它作为 DOM 类型的一部分随 lib.dom.d.ts 提供,描述了浏览器中可用的方法。

当第三方脚本(或我们自己的代码)向window添加内容时,问题就出现了:

ini 复制代码
window.X = Date.now();

这是一个问题,因为 TypeScript 不知道 X 属性,所以当你尝试访问它时会抛出错误:

所以,我们需要以某种方式更改 Window 的全局定义,以包含 TypeScript 不知道的新属性。

解决方案 1:在 .ts.tsx 文件中使用 declare global

第一个解决方案是使用 declare global 来更改 Window 的全局定义:

typescript 复制代码
declare global {
  interface Window {
    X: number;
  }
}

这之所以有效有两个原因。首先,declare global 告诉 TypeScript,其中的内容应该添加到全局作用域中。

其次,我们利用了声明合并。这是 TypeScript 中的一个规则,同一作用域中同名的接口会合并。因此,通过在同一作用域中重新声明 Window,我们可以向它添加新属性。

如果我们使用 type,这将不起作用,因为类型不支持声明合并。

这个解决方案只在 .ts.tsx 文件中有效,因为 declare global 只在模块内工作。所以这个解决方案在项目中放置定义的位置有点尴尬。在自己的模块中?与其他地方一起?

解决方案 2:.d.ts 文件

一个更整洁的解决方案是使用 .d.ts 文件中的 interface Window

kotlin 复制代码
// window.d.ts(选择你喜欢的任何文件名)

interface Window {
  X: number;
}

这之所以有效,是因为你在 .d.ts 中放置的任何内容都会自动进入全局作用域,所以不需要 declare global

它还允许你将全局定义放在一个单独的文件中,这比试图弄清楚要放在哪个 .ts 文件中要干净一些。

解决方案 3:单模块覆盖

如果你担心将类型添加到全局作用域,你可以使用 declare const window 在单个模块中覆盖 window 的类型:

sql 复制代码
declare const window: {
  X: number;
} & Window;

declare const window 就像 const window,但在类型层面上。所以它只作用于当前作用域------在这种情况下,是模块。我们声明类型为当前的 Window 加上新属性 X

如果你需要在多个文件中访问 window.X,这个解决方案会有点烦人,因为你需要在每个文件中添加 declare const window 行。

我应该使用哪种解决方案?

就我个人而言,我倾向于使用解决方案 2------一个 .d.ts 文件。它是代码行数最少的,也最容易放在项目中。

我不介意将类型添加到全局作用域。通过实际更改 Window 的类型,你更准确地描述了你的代码执行的环境。在我看来,这是一个加分项。

但如果你真的担心这个问题,使用 declare const 解决方案。

相关推荐
崔庆才丨静觅10 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606111 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊12 小时前
jwt介绍
前端
爱敲代码的小鱼12 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax