注释从这开始~

总览

当咱们试图拜访一个类型为HTMLElement的元素上的value属性时,会产生"Property 'value' does not exist on type 'HTMLElement'"谬误。为了解决该谬误,在拜访属性之前,应用类型断言将元素类型断言为HTMLInputElement

这里有个示例用来展现谬误是如何产生的。

// App.tsximport {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.tsximport {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.tsximport {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.tsximport {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