When looking at the sourcecode for a tslint rule, I came across the following statement:
if (node.parent!.kind === ts.SyntaxKind.ObjectLiteralExpression) {
Louis' answer is great, but I thought I would try to sum it up succinctly:
The bang operator tells the compiler to temporarily relax the "not null" constraint that it might otherwise demand. It says to the compiler: "As the developer, I know better than you that this variable cannot be null right now".
That's the non-null assertion operator. It is a way to tell the compiler "this expression cannot be null
or undefined
here, so don't complain about the possibility of it being null
or undefined
." Sometimes the type checker is unable to make that determination itself.
It is explained here:
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 operationx!
produces a value of the type ofx
withnull
andundefined
excluded. Similar to type assertions of the forms<T>x
andx as T
, the!
non-null assertion operator is simply removed in the emitted JavaScript code.
I find the use of the term "assert" a bit misleading in that explanation. It is "assert" in the sense that the developer is asserting it, not in the sense that a test is going to be performed. The last line indeed indicates that it results in no JavaScript code being emitted.
With the non-null assertion operator we can tell the compiler explicitly that an expression has value other than null
or undefined
. This is can be useful when the compiler cannot infer the type with certainty but we more information than the compiler.
TS code
function simpleExample(nullableArg: number | undefined | null) {
const normal: number = nullableArg;
// Compile err:
// Type 'number | null | undefined' is not assignable to type 'number'.
// Type 'undefined' is not assignable to type 'number'.(2322)
const operatorApplied: number = nullableArg!;
// compiles fine because we tell compiler that null | undefined are excluded
}
Compiled JS code
Note that the JS does not know the concept of the Non-null assertion operator since this is a TS feature
"use strict";
function simpleExample(nullableArg) {
const normal = nullableArg;
const operatorApplied = nullableArg;
}