Last updated: Feb 28, 2024
Reading timeยท7 min
The 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.
This is the index.html
file for the examples.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> </head> <body> <input id="first_name" type="text" name="first_name" value="Initial Value" /> <script src="./src/index.ts"></script> </body> </html>
And here is an example of how the error occurs in the index.ts
file.
// ๐๏ธ const input: HTMLElement | null const input = document.getElementById('first_name'); if (input != null) { // โ๏ธ Error: Property 'value' does not exist on type 'HTMLElement'.ts(2339) const value = input.value; }
The reason we got the error is that
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).
const input = document.getElementById('first_name') as HTMLInputElement | null; if (input != null) { const value = input.value; console.log(value); // ๐๏ธ "Initial value" }
Type assertions are used when we have information about the type of a value that TypeScript can't know about.
input
variable stores anHTMLInputElement
or a null
value and not to worry about it.We used a union type to specify
that the variable could still be null
, because if an HTML element with the
provided id
does not exist in the DOM, the getElementById()
method returns a
null
value.
We used a simple if
statement that serves as a
type guard to make sure the input
variable doesn't store a null
value before accessing its value
property.
const input = document.getElementById('first_name') as HTMLInputElement | null; // ๐๏ธ input has type HTMLInputElement or null here if (input != null) { // ๐๏ธ input has type HTMLInputElement here const value = input.value; console.log(value); // ๐๏ธ "Initial value" }
input
variable has a type of HTMLInputElement
in the if
block and allows us to directly access its value
property.You might also use the
optional chaining (?.) operator to
short-circuit if the reference is equal to null
or undefined
const input = document.getElementById('first_name') as HTMLInputElement | null; // ๐๏ธ using optional chaining (?.) const value = input?.value; console.log(value); // ๐๏ธ Initial value
The optional chaining operator short-circuits returning undefined
if the
reference is equal to 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.
For example as HTMLInputElement
, HTMLButtonElement
, HTMLAnchorElement
,
HTMLImageElement
, HTMLTextAreaElement
, etc - depending on the type of
element you are working with.
The types are consistently named as HTML***Element
. Once you start typing
HTML..
, your IDE should be able to help you with autocomplete.
// โ Property value const input = document.getElementById('input') as HTMLInputElement | null; if (input != null) { const value = input.value; console.log(value); } // --------------------------- // โ Property href const link = document.getElementById('link') as HTMLAnchorElement | null; if (link != null) { const href = link.href; console.log(href); } // --------------------------- // โ Property disabled const btn = document.getElementById('btn') as HTMLButtonElement | null; if (btn != null) { btn.disabled = true; } // --------------------------- // โ Property focus const input2 = document.querySelector('#first_name') as HTMLElement | null; if (input2 != null) { input2.focus(); } // --------------------------- // โ Property checked const input3 = document.getElementById('subscribe') as HTMLInputElement | null; if (input3 != null) { input3.checked = true; }
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.
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.
Here is an example of how the error occurs.
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> ); }
We got the error 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).
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.
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.
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
.
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
).
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.
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> ); }
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.
The error "Property 'style' does not exist on type 'Element'" occurs when we
try to access the style
property on an element that has a type of Element
.
To solve the error, use a type assertion to type the element as HTMLElement
before accessing the property.
This is the index.html
file for the examples.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> </head> <body> <div id="box">bobbyhadz.com</div> <script src="./src/index.ts"></script> </body> </html>
And here is an example of how the error occurs in the index.ts
file.
// ๐๏ธ const box: Element | null const box = document.querySelector('#box'); if (box != null) { // โ๏ธ Property 'style' does not exist on type 'Element'.ts(2339) box.style.backgroundColor = 'salmon'; }
The reason we got the error is that the return type of the
document.querySelector method is
Element | null
and the style
property doesn't exist on the Element
type.
To solve the error, use a type assertion to type the element as an
HTMLElement
.
const box = document.querySelector('#box') as HTMLElement | null; if (box != null) { box.style.backgroundColor = 'salmon'; }
HTMLCollectionOf
with getElementsByClassName
If you used the
document.getElementsByClassName
method, type the collection as HTMLCollectionOf<HTMLElement>
.
// ๐๏ธ with getElementsByClassName // type as HTMLCollectionOf<HTMLElement> const boxes = document.getElementsByClassName( 'box', ) as HTMLCollectionOf<HTMLElement>; for (let i = 0; i < boxes.length; i++) { boxes[i].style.backgroundColor = 'salmon'; }
We could have also used the more specific HTMLDivElement
type because we are
typing a div
element.
Type assertions are used when we have information about the type of a value that TypeScript can't know about.
box
variable stores anHTMLElement
or a null
value and not to worry about it.We used a union type to specify
that the variable could still be null
, because if an HTML element with the
provided selector does not exist in the DOM, the querySelector()
method
returns a null
value.
if
statement as a type guardWe used a simple if
statement that serves as a
type guard to make sure the box
variable doesn't store a null
value before accessing its style
property.
// ๐๏ธ const box: Element | null const box = document.querySelector('#box') as HTMLElement | null; // ๐๏ธ box has type Element or null here if (box != null) { // ๐๏ธ box has type Element here box.style.backgroundColor = 'salmon'; }
box
variable has a type of HTMLElement
in the if
block and allows us to directly access its style
property.It's always a best practice to include null
in the type assertion because the
querySelector()
method would return null
if no element with the provided
selector was found.
You can learn more about the related topics by checking out the following tutorials: