Type 'HTMLElement or null' is not assignable to type in TS

avatar

Borislav Hadzhiev

Last updated: Mar 31, 2022

banner

Photo from Unsplash

Type 'HTMLElement or null' is not assignable to type in TS #

The "Type 'HTMLElement | null' is not assignable to type" error occurs when a possibly null value is assigned to something that expects an element. To solve the error, use a non-null assertion or a type guard to verify the value is an element before the assignment.

htmlelement or null not assignable type

This is the HTML code for the examples in this article.

index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> </head> <body> <input id="submit" type="submit" name="submit" /> <script src="./src/index.ts"></script> </body> </html>

And here are 3 examples of how the error occurs.

src/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); // ⛔️ Type 'HTMLElement | null' is not assignable to type 'HTMLElement'. // Type 'null' is not assignable to type 'HTMLElement'.ts(2322) const el1: HTMLElement = input; // --------------------------------------- // ⛔️ Type 'HTMLElement | null' is not assignable to type 'Element'. // Type 'null' is not assignable to type 'Element'.ts(2322) const el2: Element = input; // --------------------------------------- function example(el: Element) { return el; } // ⛔️ Argument of type 'HTMLElement | null' is not assignable // to parameter of type 'Element'. // Type 'null' is not assignable to type 'Element'.ts(2345) example(input);

The input variable has a type of HTMLElement | null.

The el1 and el2 variables have a type of HTMLElement and Element, so they only expect to get assigned a value of that type.

TypeScript is basically telling us that the input variable might have a value of null, which is not compatible with the type of the el1 variable, which only expects an HTMLElement.

Here are a couple of examples of how you can solve the error.

src/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const el1: HTMLElement = input!; // 👈️ non-null assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const el2: Element = input!; // 👈️ non-null assertion function example(el: Element) { return el; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion example(input!); // 👈️ non-null assertion

The exclamation mark is the non-null assertion operator in TypeScript.

It removes null and undefined from a type without doing any explicit type checking.

When you use this approach, you basically tell TypeScript that this value will never be null or undefined.

This is very similar to a type assertion and should only be used when you're absolutely sure that the value is of the expected type.

src/index.ts
const input = document.getElementById('submit'); const el1: HTMLElement = input as HTMLElement; // 👈️ type assertion const el2: Element = input as Element; // 👈️ type assertion function example(el: Element) { return el; } example(input as HTMLElement); // 👈️ type assertion

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 el1 will be an HTMLElement and not to worry about it.

You can also use a type assertion directly when selecting the element.

src/index.ts
// 👇️ used type assertion here const input = document.getElementById('submit') as HTMLInputElement; const el1: HTMLElement = input; const el2: Element = input; function example(el: Element) { return el; } example(input);

We typed the input element as HTMLInputElement effectively removing null from its type.

The types are consistently named HTML***Element. Once you start typing HTML.., your IDE should be able to help you with autocomplete.

Some commonly used types are: HTMLInputElement, HTMLButtonElement, HTMLAnchorElement, HTMLImageElement , HTMLDivElement, HTMLTextAreaElement, etc.

An alternative and much better approach is to use a type guard.

src/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); function example(el: Element) { return el; } if (input != null) { const el1: HTMLElement = input; const el2: Element = input; example(input); }

The if statement serves as a type guard. We explicitly check if the input variable does not store a null value.

src/index.ts
// 👇️ const input: HTMLElement | null const input = document.getElementById('submit'); // 👉️ input has type HTMLElement or null here if (input != null) { // 👉️ input has type HTMLElement here const el1: HTMLElement = input; const el2: Element = input; example(input); } function example(el: Element) { return el; }

TypeScript knows that the input variable has a type of HTMLElement in the if block and allows us to directly assign it to the el1 and el2 variables.

Conclusion #

The "Type 'HTMLElement | null' is not assignable to type" error occurs when a possibly null value is assigned to something that expects an element. To solve the error, use a non-null assertion or a type guard to verify the value is an element before the assignment.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.