What Is the Use of Exclamation Mark Operator in TypeScript?
You might have seen an exclamation mark after a variable name, for example person!.name
. The language feature is called Non-null assertion operator. What is the purpose of the operator and when should you use it? I try to answer those questions in this blog post by giving a use-case from a real-life project.
Non-null assertion operator
In the What's New TypeScript wiki section the operator is described as following:
A new ! post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact. Specifically, the operation x! produces a value of the type of x with null and undefined excluded.
The description contains many fancy words, but in plain English, it means: when you add an exclamation mark after variable/property name, you're telling to TypeScript that you're certain that value is not null or undefined.
Next, I'll show an example where I am sure value if non-null, but I need to tell it to the TypeScript explicitly.
The example usage
I had a React component that received translation functionality from an HOC (Higher-Order Component). Okay, that's a mouthful already, before going forward I'll explain the sentence.
react-i18next library gives translation functionality by wrapping the target component inside i18next component.
import * as React from 'react'
import { translate } from 'react-i18next'
interface MyComponentProps {
t?: TranslationFunction
}
const MyComponent = ({
t
}: MyComponentProps) => (
<div>
</div>
)
export default translate()(MyComponent) // <-- this line will do the wrapping
See how in the MyComponentProps the translation function t
is optional? The reason for setting it optional is that users of the component should not have to provide translation property as it is coming from the HOC.
I know that t
is provided, so writing null checks like t ? t('my_translation_key') : ''
in every place where I want translated text is really frustrating.
Instead, I can safely write t!('my_translation_key')
without null or undefined checks.
In other words, the Non-null assertion operator decreased the possible types from TranslationFunction | undefined
to just TranslationFunction
.