Borislav Hadzhiev
Tue Mar 29 2022·2 min read
Photo by Chad Madden
The error "Property 'rows' does not exist on type 'HTMLElement'" occurs when
we try to access the rows
property on an element that has a type of
HTMLElement
. To solve the error, use a type assertion to type the element as
HTMLTableElement
before accessing the property.
This is the index.html
file for the examples in this article.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> </head> <body> <table id="table"> <thead> <tr> <th colspan="2">The table header</th> </tr> </thead> <tbody> <tr> <td>Column 1</td> <td>Column 2</td> </tr> <tr> <td>Column 1</td> <td>Column 2</td> </tr> </tbody> </table> <script src="./src/index.ts"></script> </body> </html>
And here is an example of how the error occurs in the index.ts
file.
// 👇️ const table: HTMLElement | null const table = document.getElementById('table'); // ⛔️ Property 'rows' does not exist on type 'HTMLElement'.ts(2339) const rows = table?.rows;
The reason we got the error is because the return type of the
document.getElementById
method is HTMLElement | null
and the
rows
property doesn't exist on the HTMLElement
type.
To solve the error, use a type assertion to type the element as an
HTMLTableElement
.
const table = document.getElementById('table') as HTMLTableElement | null; const rows = table?.rows; console.log(rows); // 👉️ HTMLCollection(3) [tr, tr, tr]
Type assertions are used when we have information about the type of a value that TypeScript can't know about.
table
variable stores anHTMLTableElement
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 the
optional chaining (?.)
operator to get around the possibly null
value in the example.
const table = document.getElementById('table') as HTMLTableElement | null; // 👇️ optional chaining (?.) const rows = table?.rows; console.log(rows); // 👉️ HTMLCollection(3) [tr, tr, tr]
The optional chaining operator short-circuits returning undefined
if the
reference is equal to null
or undefined
.
table
variable stores a null
value, we won't attempt to access the rows
property on null
and get a runtime error.Alternatively, you can use a simple if
statement that serves as a
type guard.
const table = document.getElementById('table') as HTMLTableElement | null; // 👉️ table has type HTMLTableElement or null here if (table != null) { // 👉️ table has type HTMLTableElement here const rows = table.rows; console.log(rows); // 👉️ HTMLCollection(3) [tr, tr, tr] }
We explicitly check that the table
variable does not store a null
value.
TypeScript knows that the table
variable has a type of HTMLTableElement
in
the if
block and allows us to directly access the rows
property.
Which approach you pick to exclude null
from the type before accessing the
rows
property is a matter of personal preference.
However, 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.