React报错之Property 'X' does not exist on type 'HTMLElement'
正文从这开始~
总览
在React中,当我们试图访问类型为HTMLElement
的元素上不存在的属性时,就会发生Property 'X' does not exist on type 'HTMLElement'错误。为了解决该错误,在访问属性之前,使用类型断言来正确地类型声明元素。
这里有三个例子来展示错误是如何发生的。
// App.tsx
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
const input = document.getElementById('first_name');
// ️ Property 'value' does not exist on type 'HTMLElement'.ts(2339)
console.log(input?.value);
// -----------------------------------------------------------------
const link = document.getElementById('link');
// ️ Property 'href' does not exist on type 'HTMLElement'.ts(2339)
console.log(link?.href);
// -----------------------------------------------------------------
const button = document.getElementById('btn');
if (button != null) {
// ️ Property 'disabled' does not exist on type 'HTMLElement'.ts(2339)
button.disabled = true;
}
}, []);
return (
<div>
<input
id="first_name"
type="text"
name="first_name"
defaultValue="Initial Value"
/>
<a id="link" href="<https://google.com>" target="_blank" rel="noreferrer">
Open Google
</a>
<button id="btn">Submit</button>
</div>
);
}
产生错误的原因是,document.getElementById
方法的返回类型是HTMLElement | null
,但是我们试图访问的属性不存在于HTMLElement
类型。
类型断言
为了解决这个错误,使用类型断言来为元素正确地进行类型声明。比如说,类型断言为HTMLInputElement
, HTMLButtonElement
, HTMLAnchorElement
, HTMLImageElement
, HTMLDivElement
, HTMLTextAreaElement
等等。这取决于你所处理的元素。
这些类型始终命名为HTML***Element
。一旦你开始输入HTML…
,你的IDE将会帮你自动补全。
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
// type elements correctly via type assertions
const input = document.getElementById('first_name') as HTMLInputElement;
console.log(input?.value);
const link = document.getElementById('link') as HTMLAnchorElement;
console.log(link?.href);
const button = document.getElementById('btn') as HTMLButtonElement;
if (button != null) {
button.disabled = true;
}
}, []);
return (
<div>
<input
id="first_name"
type="text"
name="first_name"
defaultValue="Initial Value"
/>
<a id="link" href="<https://google.com>" target="_blank" rel="noreferrer">
Open Google
</a>
<button id="btn">Submit</button>
</div>
);
}
类型断言被用于我们知道值的类型信息,但是TypeScript却不知道的时候。
我们明确的告诉TypeScript,
input
变量上存储了HTMLInputElement
,并让TS不要担心。
同样的,我们将link
变量类型声明为HTMLAnchorElement
,将btn
变量类型声明为HTMLButtonElement
。
你可以在访问一个属性之前,内联使用类型断言。
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
const value = (document.getElementById('first_name') as HTMLInputElement).value;
console.log(value);
}, []);
return (
<div>
<input
id="first_name"
type="text"
name="first_name"
defaultValue="Initial Value"
/>
<a id="link" href="<https://google.com>" target="_blank" rel="noreferrer">
Open Google
</a>
<button id="btn">Submit</button>
</div>
);
}
如果你只需要访问属性一次,并且不希望将元素分配给变量,那么内联类型声明可以完成这项工作。
如果你想更精确地处理元素的类型,可以使用联合类型将类型声明为HTML***Element | null
。
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
const input = document.getElementById(
'first_name',
) as HTMLInputElement | null;
console.log(input?.value);
const link = document.getElementById('link') as HTMLAnchorElement | null;
console.log(link?.href);
const button = document.getElementById('btn') as HTMLButtonElement | null;
if (button != null) {
button.disabled = true;
}
}, []);
return (
<div>
<input
id="first_name"
type="text"
name="first_name"
defaultValue="Initial Value"
/>
<a id="link" href="<https://google.com>" target="_blank" rel="noreferrer">
Open Google
</a>
<button id="btn">Submit</button>
</div>
);
}
HTML***Element
或者null
类型是最准确的类型,因为如果DOM元素上不存在id
属性,那么document.getElementById()
将会返回null
。
你可以使用可选链操作符(?.
)在访问属性之前来进行短路运算,如果引用是空值(null
或者undefined
)的话。
或者,你可以使用简单的if
语句作为类型守卫,就像我们对button
处理的那样。
总结
最佳实践是在类型断言中包含null
。因为如果元素上面不提供id
属性,那么getElementById
方法将会返回null
。
React报错之Property 'X' does not exist on type 'HTMLElement'的更多相关文章
- React报错之Property 'value' does not exist on type 'HTMLElement'
正文从这开始~ 总览 当我们试图访问一个类型为HTMLElement的元素上的value属性时,会产生"Property 'value' does not exist on type 'HT ...
- React报错之Property 'value' does not exist on type EventTarget
正文从这开始~ 总览 当event参数的类型不正确时,会产生"Property 'value' does not exist on type EventTarget"错误.为了解决 ...
- React报错之Parameter 'props' implicitly has an 'any' type
正文从这开始~ 总览 当我们没有为函数组件或者类组件的props声明类型,或忘记为React安装类型声明文件时,会产生"Parameter 'props' implicitly has an ...
- React报错之Parameter 'event' implicitly has an 'any' type
正文从这开始~ 总览 当我们不在事件处理函数中为事件声明类型时,会产生"Parameter 'event' implicitly has an 'any' type"错误.为了解决 ...
- 解决TS报错Property 'style' does not exist on type 'Element'
在使用queryselector获取一个dom元素,编译时却报错说property 'style' does not exist on type 'element'. 原因:这是typescript的 ...
- react 报错的堆栈处理
react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...
- elasticsearch查询:启动项目报错No property ... found for...Did you mean '...'?
网上找的案例是: 实体类字段定义:private String sku_no;dao中接口名定义:Goods findBySkuNo(String skuNo);spring-data按照接口方法定义 ...
- react中使用typescript时,error: Property 'setState' does not exist on type 'Home'
问题描述: 我在react中用typescript时,定义一个Home组件,然后在组件里用setState时会有这样一个报错:(如图)Property 'setState' does not exis ...
- notification 报错the method build() is undefined for the type Notificatin.Builder
notification 报错the method build() is undefined for the type Notificatin.Builder 这事api版本号太低导致的 Notifi ...
随机推荐
- unity---给物体施加普通力和位置力
普通力 让物体沿着某一方向获得一个力,vector3方向 addForceObj.GetComponent<Rigidbody>().AddForce(1000,0,1000); 位置力 ...
- 代码模板整理(0):先水一波a+b
梦开始的地方 "Hello World!" #include<bits/stdc++.h> using namespace std; int main(){ cout& ...
- Redis初启(一)
1.数据库存存储性能优化 在mysql的文章专题中我写过了关于传统关系型数据库的一些优化思路,整体来说,通过优化之后能够提升程序访问数据库的计算性能.但是还是有一些情况,即便是优化之后,使用传统关系型 ...
- ExtJS 同行表单域对齐有误处理办法
更新记录 2022年5月29日 第一次编辑.使用的ExtJS版本:ExtJS 7.4 问题 原本都是显示正常的表单域,比如这些文本框.选择框都是正常. 在用户进行操作,然后显示验证提示后,明显出现了问 ...
- Flutter 实现“斑马纹”背景(需要变换颜色)
Flutter 实现"斑马纹"背景 由于工作中项目需求,需要将H5转换为Flutter代码. 其中的斑马纹背景需要根据接口返回的颜色来渲染,所以不能只是图片形式,无法通过decor ...
- BUUCTF-你竟然赶我走
你竟然赶我走 首先看到这个图片没啥感觉,直接用16进制打开了.拖到最下面果然有flag flag{stego_is_s0_bor1ing}
- 实现领域驱动设计 - 使用ABP框架 - 解决方案概览
.NET解决方案的分层 下图显示了使用ABP的 应用启动模板 创建的Visual Studio解决方案: 解决方案名称为问题跟踪,它由多个项目组成.通过考虑DDD原则以及开发和部署实践,该解决方案是分 ...
- 实现领域驱动设计 - 使用ABP框架 - 什么是领域驱动设计?
前言: 最近看到ABP官网的一本电子书,感觉写的很好,翻译出来,一起学习下 (Implementing Domain Driven Design) https://abp.io/books DDD简介 ...
- tail -f 、tail -F、tailf的区别
三者经常在工作中会使用到,以下是三条命令的区别,帮忙大家理解:1.tail -f 等同于--follow=descriptor,根据文件描述符进行追踪,当文件改名或被删除,追踪停止,但是不是断开. 2 ...
- netty系列之:kequeue传输协议详解
目录 简介 KQueueEventLoopGroup KQueueEventLoop KQueueServerSocketChannel和KQueueSocketChannel 总结 简介 在前面的章 ...