React报错之Property 'value' does not exist on type 'HTMLElement'
正文从这开始~
总览
当我们试图访问一个类型为HTMLElement
的元素上的value
属性时,会产生"Property 'value' does not exist on type 'HTMLElement'"错误。为了解决该错误,在访问属性之前,使用类型断言将元素类型断言为HTMLInputElement
。
这里有个示例用来展示错误是如何发生的。
// App.tsx
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
const input = document.getElementById('message');
// ⛔️ Property 'value' does not exist on type 'HTMLElement'.ts(2339)
console.log(input?.value);
}, []);
return (
<div>
<input id="message" defaultValue="Initial value" />
</div>
);
}
我们得到错误的原因是因为,document.getElementById方法返回的类型为HTMLElement | null
,并且value属性不存在于HTMLElement
类型上。
类型断言
为了解决该错误,使用类型断言将元素类型断言为HTMLInputElement
(或者HTMLTextAreaElement
,如果你使用textarea
元素键入)。
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
// ✅ type element as HTMLInputElement
const input = document.getElementById('message') as HTMLInputElement;
console.log(input?.value); // ?️ "Initial value"
}, []);
return (
<div>
<input id="message" defaultValue="Initial value" />
</div>
);
}
你也可以在内联中使用一个类型断言,就在访问值属性之前。
// App.tsx
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
// ?️ inline type assertion
const value = (document.getElementById('message') as HTMLInputElement).value;
console.log(value);
}, []);
return (
<div>
<input id="message" defaultValue="Initial value" />
</div>
);
}
当我们拥有一个值的类型信息,但是TypeScript无从得知时,就会使用类型断言。
我们有效地告诉TypeScript,
input
变量存储了一个HTMLInputElement
,不用担心它。
如果你正在使用一个textarea
元素,你将使用HTMLTextAreaElement
类型来代替。
联合类型
如果你想更精确地控制类型,你可以使用一个联合类型来设置类型为HTMLInputElement | null
。
// App.tsx
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
// ✅ type element as HTMLInputElement | null
const input = document.getElementById('message') as HTMLInputElement | null;
console.log(input?.value); // ?️ "Initial value"
}, []);
return (
<div>
<input id="message" defaultValue="Initial value" />
</div>
);
}
HTMLInputElement | null
类型是正确的,因为如果提供id的元素不存在于DOM中,document.getElementById()
方法就会返回一个null
值。
需要注意的是,我们使用了可选链(?.
)操作符来短路运算,如果引用是空值的话(null
或者undefined
)。
换句话说,如果input
变量存储了一个null
值,我们就不会试图访问null
的属性,而得到一个运行时错误。
类型守卫
你也可以使用一个简单的if
语句作为类型守卫,以确保input
变量不存储一个null
值。
// App.tsx
import {useEffect} from 'react';
export default function App() {
useEffect(() => {
const input = document.getElementById('message') as HTMLInputElement | null;
if (input != null) {
console.log(input.value); // ?️ "Initial value"
}
}, []);
return (
<div>
<input id="message" defaultValue="Initial value" />
</div>
);
}
TypeScript知道
input
变量在if
块中的类型是HTMLInputElement
,并允许我们直接访问其value
属性。
在类型断言中包含null
总是一种最佳实践,因为如果没有找到所提供的id
的元素,getElementById
方法将返回null
。
相关文章
- 使用Commons Logging
- 记一次 .NET 某自动化采集软件 崩溃分析
- [C# 中的序列化与反序列化](.NET 源码学习)
- .NET 向量类型的运算结果范例——用于学习Vector类所提供百多个向量方法
- 树莓派(香橙派)通过.NET IoT 操作SPI编写屏幕驱动 顺手做个四足机器人(一)
- WPF自定义控件之消息提示
- .NET跨平台框架选择之一 - Avalonia UI
- 篇(16)-Asp.Net Core入门实战-权限管理之用户创建与关联角色(ViewModel再用与模型验证二)
- 学习ASP.NET Core Blazor编程系列十——路由(下)
- 代码生成器(CodeBuilder) 2.9.4 稳定版
- 篇(15)-入门实战-权限管理之用户创建与关联角色(ViewModel再用与模型验证一)
- 篇(14)-Asp.Net Core入门实战-权限管理之角色编辑和赋权(ViewModel-DTO初探)
- 算法-2 选择排序、冒泡排序、插入排序
- 篇(13)-Asp.Net Core入门实战-将功能代码增加异步功能Async和配置简单防范CSRF攻击
- NET 6 实现滑动验证码(一)、创建工程
- 算法-1 算法复杂度
- 在WPF中使用Prism弹出自定义窗体样式的对话框
- 使用Fody时,CS-SCRIPT动态代码无法找到程序集
- C# 使用SIMD向量类型加速浮点数组求和运算(3):循环展开
- aspnetcore两种上传图片(文件)的方式