Non-null assertion with getElementById
When I make a Vite TypeScript React app, it is created like this:
createRoot(document.getElementById('root')!).render(<App />);As we learn and get more proficient at TypeScript, we may wonder: What’s going
on with that exclamation mark(!)?
The ! is TypeScript is the non-null assertion operator. It’s a way of saying
to the compiler: “I know that this is not null; don’t check it.”
Without it, you’ll see code like this on apps that developers have converted to
TypeScript, checking for root with an if statement before trying to render the
app.
const root = document.getElementById('root');
if (!root) { throw new Error('Root element not found');}
createRoot(root).render(<App />);While I love a good explicit type check, in this context we control both
index.html and app.tsx. Short of user error, root will always exist. And
if it didn’t, the application wouldn’t start. The non-null assertion operator
states explicitly this thing that we know is true.
One thing to keep in mind: the non-null assertion is compile-time only. TypeScript removes it from the emitted JavaScript, so this:
createRoot(document.getElementById('root')!).render(<App />);is the same at runtime as calling createRoot on whatever getElementById
returned, including null. The ! silences the type checker; it does not guard
the call.