(React) Property 'value' does not exist on type HTMLElement

avatar

Borislav Hadzhiev

Wed Apr 06 20223 min read

banner

Photo by Oriento

(React) Property 'value' does not exist on type HTMLElement #

The React.js error "Property 'value' does not exist on type 'HTMLElement'" occurs when we try to access the value property on an element that has a type of HTMLElement. To solve the error, use a type assertion to type the element as HTMLInputElement before accessing the property.

property value does not exist on type htmlelement

Here is an example of how the error occurs.

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> ); }

The reason we got the error is because the return type of the document.getElementById method is HTMLElement | null and the value property doesn't exist in the HTMLElement type.

To solve the error, use a type assertion to type the element as an HTMLInputElement (or HTMLTextAreaElement if you're typing a textarea element).

App.tsx
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> ); }

You can also use a type assertion inline, right before accessing the value property.

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> ); }

Type assertions are used when we have information about the type of a value that TypeScript can't know about.

We effectively tell TypeScript that the input variable stores anHTMLInputElement and not to worry about it.

If you are working with a textarea element, you would use the HTMLTextAreaElement type instead.

If you want to be more precise with the type, you can use a union to set the type to 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> ); }

The HTMLInputElement | null type is correct because if an element with the provided id does not exist in the DOM, the document.getElementById() method returns a null value.

Notice that we used the optional chaining (?.) operator to short-circuit if the reference is nullish (null or undefined).

In other words, if the input variable stores a null value, we won't attempt to access the value property on null and get a runtime error.

You can also use a simple if statement that serves as a type guard to make sure the input variable doesn't store a null value.

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 knows that the input variable has a type of HTMLInputElement in the if block and allows us to directly access its value property.

It's always a best practice to include null in the type assertion because the getElementById method would return null if no element with the provided id was found.

Use the search field on my Home Page to filter through my more than 1,000 articles.