作者:独孤求独孤_715 | 来源:互联网 | 2023-01-21 17:12
在React中,当咱们试图拜访类型为HTMLElement的元素上不存在的属性时,就会产生Property'X'doesnotexistontype'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 (
);
}
产生谬误的起因是,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 (
);
}
类型断言被用于咱们晓得值的类型信息,然而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 (
);
}
如果你只须要拜访属性一次,并且不心愿将元素调配给变量,那么内联类型申明能够实现这项工作。
如果你想更准确地解决元素的类型,能够应用联结类型将类型申明为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 (
);
}
HTML***Element
或者null
类型是最精确的类型,因为如果DOM元素上不存在id
属性,那么document.getElementById()
将会返回null
。
你能够应用可选链操作符(?.
)在拜访属性之前来进行短路运算,如果援用是空值(null
或者undefined
)的话。
或者,你能够应用简略的if
语句作为类型守卫,就像咱们对button
解决的那样。
总结
最佳实际是在类型断言中蕴含null
。因为如果元素下面不提供id
属性,那么getElementById
办法将会返回null
。