TS中如何正确处理window类型

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

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

alt

快速修复方案

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

alt

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

  • 要在 .ts 或 .tsx 文件中全局更改它,你可以使用 declare global 和 interface Window:
declare global {
  interface Window {
    X: number;
  }
}
  • 要在 .d.ts 文件中全局更改它,你只需指定 interface Window。
interface Window {
  X: number;
}
  • 要仅为一个文件更改它,你可以在 .ts 或 .tsx 文件中使用 declare const window:
declare const window: {
  X: number;
} & Window;

详细原因分析

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

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

window.X = Date.now();

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

alt

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

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

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

declare global {
  interface Window {
    X: number;
  }
}

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

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

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

alt

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

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

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

// window.d.ts(选择你喜欢的任何文件名)

interface Window {
  X: number;
}

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

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

解决方案 3:单模块覆盖

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

declare const window: {
  X: number;
} & Window;

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

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

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

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

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

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

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/diannao/56218.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis的应用以及Redis工具类的封装

在前后端分离的项目中,通过session和cookie的通信一般就失去效益了,即使这么做了也会产生著名的漏洞问题CSRF(Cross-site request forgery), 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。因…

Windows 11 24H2版本有哪些新功能_Windows 11 24H2十四大新功能介绍

距离上次发布的23H2版本已经过去了一年时间,现在,Win 11的24H2版本终于等到了,微软已经全面公开发布Win11 24H2版本,版本号为26100.1742,此次官宣的版本包括了消费者版、商业版、LTSC 2024版等,各种语言版本…

H.264视频,HEVC视频,VP9视频,AV1视频小知识

H.264、HEVC(H.265)、VP9和AV1是不同的视频编码格式,它们的主要区别在于压缩效率、支持的分辨率、编码技术以及专利和授权费用等方面。以下是这些编码格式的主要区别: H.264(AVC): 压缩效率&…

STM32中的RAM和ROM分别是什么

RAM(Random Access Memory,随机存取存储器)和ROM(Read-Only Memory,只读存储器)是计算机系统中的两种常见存储器类型,它们各自有不同的功能和用途。 1. RAM(内存) 定义…

如何启动hive

检查mysql是否启动 通过Navicat测试mysql是否可以连接 找打hive配置文件所在目录 检查连接mysql的账号密码是否正确,如果不正确就要修改为正确的 初始化hive元数据存储的库:schematool -dbType <database_type> -initSchema 检查mysql中是否创建hive数据库,这里看到hive数…

zookeeper客户端

启动单机版的zookeeper 配置Maven环境 (1) IDEA自带maven (2) 更新Maven库镜像地址&#xff1a; ① 拷贝D:\Program Files\JetBrains\IntelliJ IDEA 2018.3.5\plugins\maven\lib\maven3\conf\settings.xml [IntelliJ的安装目录]到 C:/用户/username/.m2 (如果.m2文件不存在&…

Android屏幕旋转流程(2)

&#xff08;1&#xff09;疑问 &#xff08;1&#xff09;settings put system user_rotation 1是什么意思&#xff1f; 答&#xff1a;设置用户期望的屏幕转向&#xff0c;0代表&#xff1a;Surface.ROTATION_0竖屏&#xff1b;1代表&#xff1a;Surface.ROTATION_90横屏&a…

cmake与c/c++拓展的关联

CMake和VSCode中的C扩展在项目管理和代码编辑中起到不同的作用。CMake用于构建系统配置&#xff0c;负责生成编译项目所需的Makefile或其他构建文件&#xff0c;而VSCode中的C扩展负责代码编辑、语法高亮、代码提示和调试等功能。 在VSCode中&#xff0c;即使CMake已经正确配置…

华宇携司法大模型亮相2024中国移动全球合作伙伴大会

2024中国移动全球合作伙伴大会于10月11日在广州琶洲保利世贸博览馆盛大开幕。本届大会以“智焕新生 共创AI时代”为主题&#xff0c;深入探讨数据、算力与人工智能如何深度融合&#xff0c;全力推进AI规模发展、规模应用&#xff0c;加快形成AI技术能力、经济效益上的规模效应&…

Android中有哪些布局方式?

Android中的布局方式是实现用户界面设计的基础&#xff0c;通过合理的布局&#xff0c;可以创建出美观且易用的应用程序界面。Android提供了多种布局方式&#xff0c;每种布局方式都有其特定的应用场景和特点。以下是对Android中主要布局方式的详细介绍&#xff1a; 一、线性布…

第十三章 RabbitMQ之消息幂等性

目录 一、引言 二、消息幂等解决方案 2.1. 方案一 2.2. 方案二 一、引言 幂等是一个数学概念&#xff0c;用函数表达式来描述是这样的&#xff1a;f(x) f(f(x)) 。在程序开发中&#xff0c;则是指同一个业务&#xff0c;执行一次或多次对业务状态的影响是一致的。有些业务…

react实现实时计时的最简方式

js中时间的处理&#xff0c;不借助于moment/dayjs这样的工具库&#xff0c;原生获取格式化的时间&#xff0c;最简单的实现方式可以参考下面这样。 实现效果 代码实现 封装hooks import { useState, useEffect } from "react";export function useCountTime() {c…

Python酷库之旅-第三方库Pandas(150)

目录 一、用法精讲 681、pandas.Timestamp.now方法 681-1、语法 681-2、参数 681-3、功能 681-4、返回值 681-5、说明 681-6、用法 681-6-1、数据准备 681-6-2、代码示例 681-6-3、结果输出 682、pandas.Timestamp.replace方法 682-1、语法 682-2、参数 682-3、…

MongoDB Shell的使用

下载地址&#xff1a;https://www.mongodb.com/try/download/shell 以下是关于如何使用 MongoDB Shell 的一些基本步骤和常见操作&#xff1a; 前提条件&#xff1a;确保已经安装并启动了 MongoDB 服务。 启动 MongoDB Shell&#xff1a;在命令行终端中输入mongosh命令。如果…

Java 拉取并解析Kafka的Topic,Insert到InfluxDB

Maven依赖 <dependencies><!-- Kafka Client --><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.4.0</version></dependency><!-- InfluxDB Client --&g…

删除 Docker 容器的日志文件

要删除 Docker 容器的日志文件,你可以通过以下几种方法来实现: 方法一:手动清理日志文件 单容器设置 1.查看容器日志文件位置: Docker 默认的日志文件存储在 /var/lib/docker/containers// 目录下。你可以通过以下命令找到具体位置: [root@BM01-cyzx-sqmygjpt-001 ~]# do…

单点登录Apereo CAS 7.1客户端登出配置及免认证页面问题

从上一篇博客中,我们已经实现了CAS客户端集成和服务端授权,能够通过统一认证登录访问系统资源了,接下来我们讲一下如何实现CAS客户端登出及免认证页面配置的问题,还有以个人见解讲一下CAS和Spring security的关系。 上一篇博客:单点登录Apereo CAS 7.1客户端集成教程-CSD…

VUE 开发——Vue学习(三)—— 智慧商城项目

目录 解释各个模块 api接口模块&#xff1a;发送ajax请求的接口模块utils工具模块&#xff1a;自己封装的一些工具方法模块components组件模块&#xff1a;全局通用的组件router路由模块&#xff1a;封装要所有路由views&#xff1a;各个页面assets&#xff1a;各种资源 van…

源码编译llama.cpp for windows on arm

源码编译llama.cpp for windows on arm 这里有编译好的&#xff0c;直接下载使用 https://github.com/turingevo/llama.cpp-build/releases 1 先编译openblas for windows on arm 查看我的文章 《源码编译 openblas for windows on arm》 2 启用OpenBlas加速 上一步openb…