It's called the "Non-null assertion operator" and it tells the compiler that x.getY() is not null.

It's a new typescript 2.0 feature and you can read about it in the what's new page, here's what it says:

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. Similar to type assertions of the forms x and x as T, the ! non-null assertion operator is simply removed in the emitted JavaScript code.

// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
    // Throw exception if e is null or invalid entity
}

function processEntity(e?: Entity) {
    validateEntity(e);
    let s = e!.name;  // Assert that e is non-null and access name
}

Edit

There's an issue for documenting this feature: Document non-null assertion operator (!)

Answer from Nitzan Tomer on Stack Overflow
๐ŸŒ
TypeScript
typescriptlang.org โ€บ docs โ€บ handbook โ€บ release-notes โ€บ typescript-2-0.html
TypeScript: Documentation - TypeScript 2.0
Specifically, the operation x! produces a value of the type of x with null and undefined excluded. Similar to type assertions of the forms <T>x and x as T, the !
๐ŸŒ
Learn TypeScript
learntypescript.dev โ€บ 07 โ€บ l2-non-null-assertion-operator
Using the non-null assertion operator | Learn TypeScript
We can, of course, use a type assertion to resolve the type error. However, the non-null assertion operator is a more concise solution to type errors that involve null or undefined. It is worth noting that if the code were more straightforward, then TypeScript would understand that text on the return statement wasn't null.
๐ŸŒ
TypeScript ESlint
typescript-eslint.io โ€บ rules โ€บ no-non-null-assertion
no-non-null-assertion | typescript-eslint
Using assertions to tell the type system new information is often a sign that code is not fully type-safe. It's generally better to structure program logic so that TypeScript understands when values may be nullable. ... interface Example { property?: string; } declare const example: Example; const includesBaz = example.property!.includes('baz'); Open in Playground
Top answer
1 of 3
170

It's called the "Non-null assertion operator" and it tells the compiler that x.getY() is not null.

It's a new typescript 2.0 feature and you can read about it in the what's new page, here's what it says:

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. Similar to type assertions of the forms x and x as T, the ! non-null assertion operator is simply removed in the emitted JavaScript code.

// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
    // Throw exception if e is null or invalid entity
}

function processEntity(e?: Entity) {
    validateEntity(e);
    let s = e!.name;  // Assert that e is non-null and access name
}

Edit

There's an issue for documenting this feature: Document non-null assertion operator (!)

2 of 3
45

Non-null assertion operator: !

  • You tells the TS compiler that the value of a variable is not null | undefined
  • Use it when you are in possession of knowledge that the TS compiler lacks.

Here is a trivial example of what it does:

let nullable1: null | number;
let nullable2: undefined | string;

let foo  = nullable1! // type foo: number
let fooz = nullable2! // type fooz: string

It basically removes null | undefined from the type


When do I use this?

Typescript is already pretty good at inferring types for example using typeguards:

let nullable: null | number | undefined;

if (nullable) {
    const foo = nullable; // ts can infer that foo: number, since if statements checks this
}

However sometimes we are in a scenario which looks like the following:

type Nullable = null | number | undefined;

let nullable: Nullable;

validate(nullable);

// Here we say to ts compiler:
// I, the programmer have checked this and foo is not null or undefined
const foo = nullable!;  // foo: number

function validate(arg: Nullable) {
    // normally usually more complex validation logic
    // but now for an example
    if (!arg) {
        throw Error('validation failed')
    }
}

My personal advice is to try to avoid this operator whenever possible. Let the compiler do the job of statically checking your code. However there are scenarios especially with vendor code where using this operator is unavoidable.

๐ŸŒ
Medium
medium.com โ€บ @tar.viturawong โ€บ a-note-on-typescript-non-null-assertion-operator-bad8fbe62bba
A note on TypeScript non-null assertion operator | by Tar Viturawong | Medium
March 25, 2019 - The assertion used in TypeScriptโ€™s release notes is an example of such a case. There is plenty of documentation why this is safe that is understandable by all. Often, if this is convoluted, itโ€™s better to self-document with an explicit type assertion. ... It is absolutely clear where the scope of your knowledge/assumption about the safety of ignoring null ...
๐ŸŒ
Sentry
sentry.io โ€บ sentry answers โ€บ react โ€บ how to fix the forbidden non-null assertion in typescript and react?
How to fix the forbidden non-null assertion in TypeScript and React? | Sentry
You can see a live demo of this error in this typescript-eslint playground. For this error to occur, the eslintrc file has the โ€œno-non-null-assertionโ€ rule set to "error": ... The Non-null Assertion Operator (Postfix !) assertion removes the null and undefined types from a value. To use it, add the ! symbol after an expression like in the console log example ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ typescript โ€บ typescript-non-null-assertion-operator-postfix-type
TypeScript Non-null Assertion Operator (Postfix !) Type - GeeksforGeeks
April 28, 2025 - Example 2: In this example:We define a User type representing a user object with potentially nullable properties. We create a user object with a name property (non-nullable) and an email property (nullable). We use the non-null assertion operator ! to assert that the email property is non-null when accessing it...
๐ŸŒ
Biome
biomejs.dev โ€บ linter โ€บ rules โ€บ no-non-null-assertion
noNonNullAssertion | Biome
Itโ€™s generally better to structure program logic so that TypeScript understands when values may be nullable. ... code-block.ts:5:21 lint/style/noNonNullAssertion FIXABLE โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” โš  Forbidden non-null assertion. 3 โ”‚ } 4 โ”‚ declare const foo: Example; > 5 โ”‚ const includesBaz = foo.property!.includes(โ€˜bazโ€™); โ”‚ ^^^^^^^^^^^^^ 6 โ”‚ โ„น Unsafe fix: Replace with optional chain operator ?.
Find elsewhere
๐ŸŒ
DEV Community
dev.to โ€บ audreyk โ€บ when-to-use-the-non-null-assertion-operator-in-typescript-545f
๐Ÿงญ ๐Ÿ‡น When to use the non-null assertion operator in TypeScript - DEV Community
August 18, 2024 - It tells TypeScript's type checker to ignore the possibility that the value is null or undefined, thus bypassing type checking for these values. Use the non-null assertion operator when you are certain that a variable will be assigned a non-null value when you access it (for example, after a ...
๐ŸŒ
Nicotsou
nicotsou.com โ€บ tltr-typescript-non-null-assertion
Dealing With Non-Null Assertions in TypeScript
An even better way is to use the Non-Null Assertion Operator: ... Mind the ! at the end of this expression. If you are something like me, you pretty much want to understand what is actually happening in the background. Here, we are basically instructing TypeScript to fallback to the type that our property isFavorite originally had, in case its value will be undefined. The choice for which approach is better, doesnโ€™t need enough mental processing power. In the last example, I didnโ€™t have to specify any value or to add additional logic.
๐ŸŒ
TypeScript ESlint
typescript-eslint.io โ€บ rules โ€บ no-extra-non-null-assertion
no-extra-non-null-assertion | typescript-eslint
export default tseslint.config({ rules: { "@typescript-eslint/no-extra-non-null-assertion": "error" } });
๐ŸŒ
Rip Tutorial
riptutorial.com โ€บ non-null assertions
TypeScript Tutorial => Non-null assertions
type ListNode = { data: number; next?: ListNode; }; function addNext(node: ListNode) { if (node.next === undefined) { node.next = {data: 0}; } } function setNextValue(node: ListNode, value: number) { addNext(node); // Even though we know `node.next` is defined because we just called `addNext`, // TypeScript isn't able to infer this in the line of code below: // node.next.data = value; // So, we can use the non-null assertion operator, !, // to assert that node.next isn't undefined and silence the compiler warning node.next!.data = value; }
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 76232881 โ€บ how-to-get-rid-of-non-null-assertion
typescript - How to get rid of non-null assertion - Stack Overflow
function greet(name: string | null): string { // Use the non-null assertion operator to assert that 'name' is not null return `Hello, ${name!.toUpperCase()}!`; } console.log(greet("Alice")); // Output: Hello, ALICE! console.log(greet(null)); // Output: Error - Runtime exception ยท please check whether the human object contains valid values. if so you could remove the non-null assertion
๐ŸŒ
GitBook
basarat.gitbook.io โ€บ typescript โ€บ intro โ€บ strictnullchecks
strictNullChecks | TypeScript Deep Dive
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. For example:
๐ŸŒ
Medium
medium.com โ€บ @kumar.suchit9 โ€บ how-to-use-the-non-null-assertion-operator-in-typescript-840f9b63d3b9
How to Use the ! (Non-Null Assertion) Operator in TypeScript | by Suchit Kumar | Medium
September 14, 2024 - Here, name is optional, but using ! asserts that it wonโ€™t be undefined when accessed. The ! operator can be extremely useful in the right situations, but it also comes with risks. When you use it, youโ€™re effectively telling TypeScript to bypass its strict type checking. If your assumption turns out to be wrongโ€”if the value actually is null or undefinedโ€”youโ€™ll get a runtime error, which TypeScript is designed to help you avoid in the first place.
Top answer
1 of 1
9

This is mostly a terminology problem:

  • null and undefined are different, even though some parts of the language treat them similarly. (For example, the non-null assertion operator eliminates both null and undefined from the domain of the expression it operates on.)

  • The ! after a class property declaration is the definite assignment assertion operator operator, not the non-null assertion operator. (They are both written with a postfix !, but a non-null assertion appears after an expression, while a definite assignment assertion appears after a variable/property declaration.) A definite assignment assertion tells the compiler that it does not need to verify that a variable or property has been initialized before use. The definite assignment assertion operator has nothing to do with null.

If you do not initialize a property or variable, its value will be undefined, not null, if you read from it. If you have the --strictPropertyInitialization compiler option enabled (or just --strict, which includes it), and you have a class property whose type does not include undefined (not null), then you must either initialize it immediately on declaration, initialize it unconditionally inside the constructor, or use a definite assignment assertion:

class Example {
    a: string | undefined; // okay: includes undefined
    b: string | null = "b"; // okay: initialized
    c: string | null; // okay: assigned in constructor
    d: string | null; // error: compiler cannot be sure it is assigned
    e!: string | null; // okay: asserted as assigned

    constructor() {
        this.c = "c";
        if (Math.random() < 1000) {
            this.d = "d"
            this.e = "e";
        }
    }
}

Playground link to code