What Is the Use of Exclamation Mark Operator in TypeScript?

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.