TS中如何正确处理window类型

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

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

alt

快速修复方案

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

alt

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

  • 要在 .ts.tsx 文件中全局更改它,你可以使用 declare globalinterface 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.mzph.cn/diannao/56218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…