Why do you want to use the "non-null assertion operator"?

The status property can either be string | undefined. What about passing an empty string or perhaps assigning a default value when you don't want to specify a value for status?

<Items status={status || ''}/>

Or:

type ItemProps = {
  status?: string;
};

const Items: React.FC<ItemProps> = ({ status = 'statusDefaultValue' }) => <div>Some JSX</div>

It's a bit hard for me to understand your case without knowing the context. Hope this can help.

Answer from HereBeAndre on Stack Overflow
🌐
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
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 above.
🌐
TypeScript
typescriptlang.org › docs › handbook › release-notes › typescript-2-0.html
TypeScript: Documentation - TypeScript 2.0
In regular type checking mode the inferred type of z is any because of widening, but in strict null checking mode the inferred type of z is null (and therefore, absent a type annotation, null is the only possible value for z). 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.
🌐
Biome
biomejs.dev › linter › rules › no-non-null-assertion
noNonNullAssertion | Biome
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. ... code-block.ts:5:21 lint/style/noNonNullAssertion FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚠ Forbidden ...
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 - It turned out that this operator ! placed after an expression is TypeScript’s non-null assertion operator.
Find elsewhere
🌐
GitHub
github.com › testing-library › dom-testing-library › issues › 981
Conflicting eslint rules re: TypeScript non-null assertions · Issue #981 · testing-library/dom-testing-library
June 15, 2021 - 122:13 error Use a ! assertion to more succintly remove null and undefined from the type @typescript-eslint/non-nullable-type-assertion-style · So I used the ! as recommended and wrote resolve(result!), but then I got an error telling me not to · 122:13 error Forbidden non-null assertion ...
Published   Jun 15, 2021
🌐
Reddit
reddit.com › r/typescript › new to ts - is this wrong?
r/typescript on Reddit: New to TS - Is this wrong?
July 26, 2022 -

Been new to TS and having only tried it long ago, I'm confused about some things.

I have a simple html page where I'm getting 2 elements from it, a button and a div, so I did:

const BUTTON: HTMLButtonElement | null = document.querySelector("#get");  
const DATA: HTMLDivElement | null = document.querySelector("#data");

Everything looks good so far, even when I know those wont be null, they could be for whatever reson I guess.

Then I have a listener so when the button is clicked I change the content on the div.

BUTTON?.addEventListener("click", async () => {  
 DATA ? DATA.textContent = "WORLD" : "";  
});  

I understand the need of using ? after BUTTON (Seams reasonable) but the part I bet I'm doing wrong is that DATA ? line... Is that what I need to write to have TS not complain about my code?

 DATA.textContent = "WORLD";

Object is possibly "null"

First my mind though... Ok you may be null so:

 DATA?.textContent = "WORLD";

That gives me The left-hand side of an assignment expression may not be an optional property access.

Then I remember I saw somewhere the ! for those cases.

DATA!.textContent = "WORLD";

And while I believe that's the "solution" I get a warning from eslint this time Forbidden non-null assertion.

Even then if DATA is null, code will throw an error, while my first piece of code wont.

What's the way to go here?

Top answer
1 of 5
13
document.querySelector returns Element | null because there's a chance that the selector ends up not matching on anything, so TypeScript forces you to handle that case explicitly. There are two ways to go about doing this: The first way is, if you're absolutely sure that the selector will always match on an element, you can use the non-null assertion operator, !. This way, you're basically telling the compiler: "Hey, I know better than you that this particular value will for sure never be null." Still, if your assumption turns out to be false for some reason, TS won't be able to protect you and you might run into runtime errors by trying to access properties on a value that's null. This is why the no-non-null-assertion ESLint rule exists. Some people argue that you should have a backup plan even if you're 100% sure the selector always matches, meaning you shouldn't use the ! operator at all. If you disagree with this stance, you can always turn off that particular rule in your ESLint config. The second way is to handle it the error case explicitly by doing something like this: if (DATA === null) { throw new Error("Could not find DATA element."); } DATA.textContent = "WORLD"; The TypeScript compiler is smart enough to figure out that, if execution manages to reach the line of code after the if block, DATA cannot be null at that point, so it's safe to access the textContent property.
2 of 5
6
It's awesome that TS can express that a variable may be T | null, and then checks for you to make sure you're handling the null (assuming strict mode is on). However, the problem as you've seen is that this "infects" all your core application logic, you have to clutter the things you're doing with null checks. Instead, consider pushing null checking to the boundaries of your application, and fail fast or handle those null cases. Then the rest of the application can work on the not-null case. For example here, is it legal for the button or data to be null? Could your app function if so? Consider instead to check these with if (!button) at the boundaries and crash/show message/log error or do whatever is appropriate. The rest of your app can be written in a way that it works on just a T, not a T | null.
🌐
SonarSource
rules.sonarsource.com › typescript › rspec-2966
Non-null assertions should not be used
Unique rules to find Bugs, Vulnerabilities, Security Hotspots, and Code Smells in your TYPESCRIPT code
🌐
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; }
🌐
Omarileon
omarileon.me › blog › typescript-non-null-assertion
mari. | Typescript Non-Null Assertions: That Weird Exclamation Mark Operator
February 2, 2024 - The non-null assertion operator, or that weird exclamation mark you might be seeing in TypeScript is an operator that tells TypeScript that a value won't be null or undefined. In a technical sense, it eliminates null and undefined from the type ...
🌐
GitHub
github.com › microsoft › TypeScript › issues › 9637
Remove the non-null assertion operator · Issue #9637 · microsoft/TypeScript
July 12, 2016 - function validateEntity(e: Entity?): e is Entity { if (e == null) { throw new Error(); } return true; } function processEntity(e: Entity?) { if (validateEntity(e)) { let s = e.name; // Guard asserts e is an Entity (and therefore non-null) and access name } }
Published   Jul 12, 2016
🌐
Learn TypeScript
learntypescript.dev › 07 › l2-non-null-assertion-operator
Using the non-null assertion operator | Learn TypeScript
The non-null assertion operator is an exclamation mark (!), and this is placed after the variable or expression that we want to tell TypeScript isn't null or undefined.
🌐
Rome
docs.rome.tools › lint › rules › nononnullassertion
Lint Rule noNonNullAssertion — Rome
Disallow non-null assertions using the ! postfix operator. TypeScript’s ! non-null assertion operator asserts to the type system that an expression is non-nullable, as in not null or undefined.
🌐
GitHub
github.com › axios › axios › discussions › 6451
...utils\request.ts 80:19 warning Forbidden non-null assertion @typescript-eslint/no-non-null-assertion · axios/axios · Discussion #6451
I'm upgrading Axios from 0.22.0 to 1.7.2. But I get now the warning: 80:19 warning Forbidden non-null assertion @typescript-eslint/no-non-null-assertion axiosInstance.interceptors.response.use( fun...
Author   axios