正文从这开始~

总览

在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. Ruby 趣学笔记(二)

    Ruby 趣学笔记(二) 本文写于 2020 年 5 月 7 日 类的继承 之前忘记写了,Ruby 的继承写法是: class IPhone < Phone def initialize(id, ...

  2. 138_Power BI&Power Pivot特殊半累加度量

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 半累加度量(semi-additive measure),在DAX建模分析的时候经常遇见:应用场景诸如银行存款. ...

  3. django框架1

    简介 1.前端    与用户打交道的界面 2.web框架    可以将前端和数据库整合到一起 3.数据库    专门用于存储数据 内容概要 纯手撸web框架 基于wsgiref模块 优化措施 动静态网 ...

  4. Linux Cgroup v1(中文翻译)(2):CPUSETS

    英文原文:https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpusets.html Copyright (C) 2004 BU ...

  5. Wireshark学习笔记(二)取证分析案例详解

    @ 目录 练习一:分析用户FTP操作 练习二:邮件读取 练习三:有人在摸鱼? 练习一:分析用户FTP操作 已知抓包文件中包含了用户登录FTP服务器并进行交互的一个过程,你能否通过wireshark分析 ...

  6. ssh打通

    打通ssh https://www.cnblogs.com/yolanda-lee/p/4975453.html

  7. 重学ES系列之拓展运算符

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 集成学习——Adaboost(手推公式)

  9. SAP Web Dynpro-使用服务调用

    创建服务调用后,功能模块可用于组件. 现在可以选择一个视图,以便在浏览器中显示数据库表的元素. 如果全局控制器不是组件控制器,则必须为所选视图的控制器输入全局控制器的使用页面. 之后,应该有该节点的映 ...

  10. Leetcode--Last Stone Weight II

    Last Stone Weight II 欢迎关注H寻梦人公众号 You are given an array of integers stones where stones[i] is the we ...