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 ...
随机推荐
- [C++STL] 队列 queue 的入门
队列结构 概念: 队列(queue):和栈相似,也是一种特殊的线性表.和栈不同的是,队列只允许在表的一端进行插入操作,而在另一端进行删除操作.一般来说,进行插入操作的一端称为队尾,进行删除操作的一端称 ...
- 网络编程之socket套接字
目录 socket套接字简介 socket模块 通信循环 代码优化 连接循环 半连接池 黏包问题 解决黏包问题 黏包问题特殊情况(文件过大) socket套接字简介 由于操作OSI七层是所有C/S架构 ...
- 第31章 Spring bean 作用域
每日一句 I must say a word about fear. It is life's only true opponent. Only fear can defeat life. 这里必须说 ...
- 介绍一个好用的dao层与mybatis互跳的idea插件MyBatisCodeHelperPro
一次点击 File--> Settings --> Plugins -->搜索MyBatisCodeHelperPro,点击获取,重启idea即可 接下来看效果,点击小企鹅就可以相互 ...
- jvm造轮子
博客内容来源于 刘欣老师的课程,刘欣老师的公众号 码农翻身 博客内容来源于 Java虚拟机规范(JavaSE7) 博客内容的源码 https://gitee.com/zumengjie/litejvm ...
- Vue2自定义插件的写法-Vue.use()
最近在用vue2完善一个项目,顺便温习下vue2的基础知识点! 有些知识点恰好没用到时间一长就会淡忘,这样对自己是一种损失. 定义一个对象 对象里可以有任何内容 但install的函数是必不可少的,因 ...
- 基于thinkphp6 layui的优秀极速后台开发框架推荐
很多时候我们在做项目开发的时候,苦于没有好一点的轮子,自己动手开发的话,太耗费时间了,如果采用VUE的话,学习成本跟调试也比较麻烦, 而且有时候选用的东西甲方也不太容易接受,现在给大家介绍一款优秀的极 ...
- 正在运行中的docker容器设置自动重启
# demo : 你的容器名称 docker update –-restart=always demo
- Golang并发编程——goroutine、channel、sync
并发与并行 并发和并行是有区别的,并发不等于并行. 并发 两个或多个事件在同一时间不同时间间隔发生.对应在Go中,就是指多个 goroutine 在单个CPU上的交替运行. 并行 两个或者多个事件在同 ...
- 015(Power string)(哈希表)
题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1457 题目思路: 思路就是预设子串的长度,从1开始,而后一段一段试 试到一个对不上的就打回 如果 ...