(React) Argument type 'HTMLElement or null' not assignable to parameter type 'Element or DocumentFragment'

avatar

Borislav Hadzhiev

Last updated: Apr 4, 2022

banner

Photo from Unsplash

(React) Argument type 'HTMLElement or null' not assignable to parameter type 'Element or DocumentFragment' #

Use a non-null assertion or a type assertion to solve the React.js error "Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | DocumentFragment'", e.g. const root = createRoot(rootElement!).

argument type htmlelement or null not assignable

Here is an example of how the error occurs.

index.tsx
import App from './App'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; const rootElement = document.getElementById('root'); // ⛔️ Argument of type 'HTMLElement | null' is not // assignable to parameter of type 'Element | DocumentFragment'. // Type 'null' is not assignable to type 'Element | DocumentFragment'.ts(2345) const root = createRoot(rootElement); root.render( <StrictMode> <App /> </StrictMode>, );

The issue here is that the return type of the document.getElementById method is HTMLElement | null.

If the provided id does not exist in the DOM, the method returns null.

On the other hand, the expected parameter type of the createRoot method is Element | DocumentFragment, so there is a mismatch between the provided argument type and the expected parameter type.

One way to solve the error is to use the non-null (!) assertion operator.

index.tsx
import App from './App'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; const rootElement = document.getElementById('root'); // 👇️ non-null (!) assertion const root = createRoot(rootElement!); root.render( <StrictMode> <App /> </StrictMode>, );
The non-null (!) assertion operator removes null and undefined from a type without doing any explicit type checking.

When you use this approach, you basically tell TypeScript that the rootElement variable will never be null or undefined. So, the rootElement variable becomes of type HTMLElement instead of HTMLElement | null.

Alternatively, you can use a simple type assertion.

index.tsx
import App from './App'; import {StrictMode} from 'react'; import {createRoot} from 'react-dom/client'; const rootElement = document.getElementById('root'); // 👇️ use type assertion const root = createRoot(rootElement as Element); root.render( <StrictMode> <App /> </StrictMode>, );

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

We are effectively telling TypeScript that the rootElement variable stores a value of type Element and not to worry about it.

We determined the correct type from the error message: "Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | DocumentFragment'".

With this error message TypeScript tells us: The function's expected parameter type is Element | DocumentFragment, but you are calling the function with an argument of type HTMLElement | null.

The types are not compatible because the argument type is possibly null.

To solve the error, we have to make the passed in argument and the expected parameter types are compatible.

Conclusion #

Use a non-null assertion or a type assertion to solve the React.js error "Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | DocumentFragment'", e.g. const root = createRoot(rootElement!).

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.