正文从这开始~

总览

在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 类型。

类型断言

为了解决这个错误,使用类型断言来为元素正确地进行类型声明。比如说,类型断言为HTMLInputElementHTMLButtonElementHTMLAnchorElementHTMLImageElementHTMLDivElementHTMLTextAreaElement等等。这取决于你所处理的元素。

这些类型始终命名为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'的更多相关文章

  1. React报错之Property 'value' does not exist on type 'HTMLElement'

    正文从这开始~ 总览 当我们试图访问一个类型为HTMLElement的元素上的value属性时,会产生"Property 'value' does not exist on type 'HT ...

  2. React报错之Property 'value' does not exist on type EventTarget

    正文从这开始~ 总览 当event参数的类型不正确时,会产生"Property 'value' does not exist on type EventTarget"错误.为了解决 ...

  3. React报错之Parameter 'props' implicitly has an 'any' type

    正文从这开始~ 总览 当我们没有为函数组件或者类组件的props声明类型,或忘记为React安装类型声明文件时,会产生"Parameter 'props' implicitly has an ...

  4. React报错之Parameter 'event' implicitly has an 'any' type

    正文从这开始~ 总览 当我们不在事件处理函数中为事件声明类型时,会产生"Parameter 'event' implicitly has an 'any' type"错误.为了解决 ...

  5. 解决TS报错Property 'style' does not exist on type 'Element'

    在使用queryselector获取一个dom元素,编译时却报错说property 'style' does not exist on type 'element'. 原因:这是typescript的 ...

  6. react 报错的堆栈处理

    react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...

  7. elasticsearch查询:启动项目报错No property ... found for...Did you mean '...'?

    网上找的案例是: 实体类字段定义:private String sku_no;dao中接口名定义:Goods findBySkuNo(String skuNo);spring-data按照接口方法定义 ...

  8. react中使用typescript时,error: Property 'setState' does not exist on type 'Home'

    问题描述: 我在react中用typescript时,定义一个Home组件,然后在组件里用setState时会有这样一个报错:(如图)Property 'setState' does not exis ...

  9. notification 报错the method build() is undefined for the type Notificatin.Builder

    notification 报错the method build() is undefined for the type Notificatin.Builder 这事api版本号太低导致的 Notifi ...

随机推荐

  1. 为什么 Redis 要有哨兵机制?

    作者:小林coding 计算机八股文刷题网站:https://xiaolincoding.com 大家好,我是小林. 这次聊聊,Redis 的哨兵机制. 提纲 为什么要有哨兵机制? 在 Redis 的 ...

  2. Python写安全小工具-TCP全连接端口扫描器

    通过端口扫描我们可以知道目标主机都开放了哪些服务,下面通过TCP connect来实现一个TCP全连接端口扫描器. 一个简单的端口扫描器 #!/usr/bin/python3 # -*- coding ...

  3. linux篇--mysql数据库备份并删除前一分钟的数据

    linux 中mysql数据库定时备份并删除前一分钟的所有数据 #!/bin/bash #mysqldump -uroot -ppassword01! imaginebase > /home/b ...

  4. async用法

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  5. 2020级cpp机考模拟题A卷-#题解2

    这部分的题目都有一定难度,有兴趣的同学可以钻研一下. 特此感谢来自BDT20030  tql的支持. 2:素数的和-2 题意: 计算不大于m的素数之和.(多么容易理解的题目啊,对吧) 题解(有点复杂的 ...

  6. 每天一个 HTTP 状态码 102

    102 Processing 102 Processing 是用于 WebDAV协议 请求的状态码. 这个状态码表示服务器已经收到了客户端的请求,正在处理,但暂时还没有可接触的响应.可以用于防止客户端 ...

  7. 配置中心Nacos(服务发现)

    服务演变之路 单体应用架构 在刚开始的时候,企业的用户量.数据量规模都⽐较⼩,项⽬所有的功能模块都放在⼀个⼯程中编码.编译.打包并且部署在⼀个Tomcat容器中的架构模式就是单体应用架构,这样的架构既 ...

  8. Lifted ElGamal 门限加密算法

    本文详细学习Lifted ElGamal 门限加密算法 门限加密体制 (1)门限加密是可以抗合谋的 (2)表现在私钥分为\(n\)份,至少需要\(t\)份才能解密成功,叫做(t-n)门限.类似于&qu ...

  9. 000 上传本地库到Github远程库过程全记录

    20220613 Github上新创建了一个CsImage库,之后本地创建了一个对应名称的目录,并创建本地库,进行了上传操作,记录一下过程 1.Github上CsImage库创建完成 Github上创 ...

  10. 技术分享 | 想做App测试就一定要了解的App结构

    本文节选自霍格沃兹测试开发学社内部教材 app 的结构包含了 APK 结构和 app 页面结构两个部分 APK结构 APK 是 Android Package 的缩写,其实就是 Android 的安装 ...