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 ...
随机推荐
- 【java并发编程】Lock & Condition 协调同步生产消费
一.协调生产/消费的需求 本文内容主要想向大家介绍一下Lock结合Condition的使用方法,为了更好的理解Lock锁与Condition锁信号,我们来手写一个ArrayBlockingQueue. ...
- Redisson批量操作类RBuckets和管道利器RBatch
<Spring Boot 整合Redisson配置篇> <Spring Boot 整合Redisson操作Redis基础篇> <Redisson批量操作类RBuckets ...
- 用 notion 管理信用卡与花呗
用 notion 管理信用卡与花呗 Notion原文,排版更佳 概述 不需要提醒功能和安卓用户可以忽略Scriptable和快捷指令 app的设置 Notion 建立信用卡表格,录入信用卡基本信息,自 ...
- CentOS7 安装高版本gcc, g++, gfortran等工具
SCL(Software Collections)是一个CentOS/RHEL Linux平台的软件多版本共存解决方案,为用户提供一种方便.安全地安装和使用应用程序和运行时环境的多个版本的方式. De ...
- python 企业微信发送文件
import os import json import urllib3 class WinxinApi(object): def __init__(self,corpid,secret,chatid ...
- 使用docker搭建jupyter notebook / jupyterlab
说明 由于官方镜像实在是不怎么好用,所以我自己做了一个优化过的jupyter notebook的镜像 notebook_hub,使用我这个镜像搭建容器非常简单,下面就基于这个notebook_hub来 ...
- 在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS
背景 阿里云OSS提供了一个Webpack插件,可在Webpack打包结束后将webpack生成的文件自动上传到阿里云OSS中 下面看看在CabloyJS中如何使用该插件 新建项目,并配置MySQL连 ...
- Camunda如何配置和使用mysql数据库
Camunda默认使用已预先配置好的H2数据库,数据库模式和所有必需的表将在引擎第一次启动时自动创建.如果你想使用自定义独立数据库,比如mysql,请遵循以下步骤: 一.新建mysql数据库 为Cam ...
- Redis的使用(二)
一.redis简单应用 其实在写这个redis专题时我想了很久,我觉得redis没什么好说的,因为现在是个人都会用redis,但是我在写netty专题时发现,netty里面很多东西和概念有很多跟red ...
- 设置C#启动进程但不显示命令行窗口
设置一下Process类型相关的配置属性即可,直接上代码. //记得引入命名空间 //using System.Diagnostics; //获得当前环境的基路径 string basePath = ...