Non Null Assertion Operator

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional TypeScript Masterclass Lessons

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11

Non Null Assertion Operator

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Motivation

TypeScript might not follow the entire code path to be sure that a value is not-null e.g. the following code will Error at compile time:

type Point = {
x: number,
y: number,
};

let point: Point;
function initialize() {
point = { x: 0, y: 0 };
}

initialize();
console.log('After initialized', point.x, point.y); // Runtime: Ok, Compiletime: Error

Fix

Use a non-null assertion operator (notice the !):

type Point = {
x: number,
y: number,
};

let point: Point;
function initialize() {
point = { x: 0, y: 0 };
}

initialize();
console.log('After initialized', point!.x, point!.y); // Runtime: Ok, Compiletime: Ok

Avoid

You should avoid when possible, e.g. restructure your code:

type Point = {
x: number,
y: number,
};

function initialize(): Point {
return { x: 0, y: 0 };
}

const point = initialize();
console.log('After initialized', point.x, point.y); // No need anymore as TypeScript can follow the code path
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

It is entirely possible to end up in a situation where typescripts code flow analysis cannot be showed that a value is null or undefined. Let's look at an example. Here. We have a type representing a point in two dimensional space with members X and Y of type number. We declare an instance of this point and then create a utility function to initialize this instance. Later on in our code, we initialize this instance and then try to access its x and Y members. At this point, you can see that TypeScript is giving us a compile time error.

00:34

The reason for this error is that TypeScript does not do deep code flow analysis and therefore does not understand the impact of calling the initialized function. Therefore, it assumes that point may or may not be still undefined, and of course we know that point can no longer be undefined and we can help TypeScript understand this fact by using a non null assertion operator. So at any point where TypeScript still thinks that point might be undefined, we use a postfix exclamation mark. And this exclamation mark is what is known as a noal assertion.

01:07

Just like other type assertions we have seen before, noal assertions are compiled time only and have no runtime impact. So it is up to you to ensure that the value is indeed not going to be null or undefined. So it is generally better to rewrite your code to avoid these non null assertions. For example, in this particular case, we can get rid of the dangling variable declaration and then rewrite the initialized function to return us the point and then only create the variable after the function has been invoked. This ensures that the point variable is always initialized

01:41

and we no longer need the nonna assertions. Now, nonna assertions can work on any variable or a member of a variable. Let's demonstrate that with another example. Here we have a type representing a person that always has a name, but may optionally have an email that can be string or now or undefined. Next, we have a utility function to send an email given an email address and just as an example, we have a mock implementation that logs out the email to the console Now to ensure that a particular person is contactable. We have this utility function

02:14

that checks if person email is equal to null or undefined, and in that case throws an error. Now if this function ever returns, that ensures that person email will not be null or undefined and therefore it must be a string. Now, in order to contact a particular person, we have this function that takes a person and the first thing it does is ensures that person email will not be null or undefined by using our utility ensure contactable function. So if this function returns, we should be able to safely invoke send email because we know that person email must be a string.

02:49

However, once more script has failed to infer this particular side effect of the ensure contactable function and therefore thinks that person email might still be no or undefined. Now just like before, we can override this error by using a non null assertion that is putting an exclamation mark after the value that Dives script thinks might be null or undefined. Also, just like before, it is up to you to ensure the correctness of your code. At this point, we can rewrite a code to make it a bit more easier for TypeScript to infer. For example, we can take the assertion from the Ensure

03:23

contactable function and move that in line. This triggers Typescripts code flow analysis four person email, and now TypeScript knows that person. Email will not be null or undefined and therefore must be a string and we'll let us safely invoke the send email function.

Professional TypeScript Masterclass

Professional TypeScript Masterclass

1.Introduction
free
⏱️ 1:54
2.Setup
free
⏱️ 5:44
3.Primitive Types
free
⏱️ 1:42
4.Instance Types
free
⏱️ 1:52
5.Arrays And Tuples
free
⏱️ 1:38
6.Objects
free
⏱️ 1:33
7.const declarations
free
⏱️ 1:03
8.Function Types
free
⏱️ 1:57
9.Structural Typing
free
⏱️ 2:10
10.Classes in TypeScript
free
⏱️ 1:48
11.Target Compiler Option
free
⏱️ 2:37
12.Generics
⏱️ 3:02
13.Special Types any And unknown
⏱️ 2:00
14.JavaScript to TypeScript
⏱️ 1:32
15.Frontend Projects
⏱️ 3:49
16.Type Assertions
⏱️ 2:15
17.Type Casting
⏱️ 1:16
18.Modules
⏱️ 1:55
19.Type Declarations
⏱️ 4:25
20.Creating NPM packages
⏱️ 3:20
21.Async Await
⏱️ 3:05
22.Running in NodeJS
⏱️ 1:40
23.Lexical this
⏱️ 2:34
24.readonly Modifier
⏱️ 1:59
25.Union Types
⏱️ 2:57
26.Literal Types
⏱️ 2:58
27.Type Narrowing
⏱️ 4:19
28.Discriminated Unions
⏱️ 3:29
29.Class Parameter Properties
⏱️ 1:02
30.Strict Compiler Option
⏱️ 6:18
31.null vs undefined
⏱️ 4:19
32.Intersection Types
⏱️ 2:03
33.Optional Modifier
⏱️ 2:47
34.Non Null Assertion Operator
⏱️ 3:40
35.Interfaces
⏱️ 2:28
36.Interface Declaration Merging
⏱️ 1:01
37.Types vs Interfaces
⏱️ 2:16
38.never Type
⏱️ 3:00
39.implements Keyword
⏱️ 1:25
40.Definite Assignment Assertion
⏱️ 2:31
41.User Defined Type Guards
⏱️ 2:02
42.Assertion Functions
⏱️ 3:42
43.Function Overloading
⏱️ 4:15
44.Call Signatures
⏱️ 2:53
45.Abstract Classes
⏱️ 1:53
46.Index Signatures
⏱️ 3:08
47.Readonly Arrays and Tuples
⏱️ 2:58
48.Double Assertions
⏱️ 2:20
49.const Assertions
⏱️ 3:55
50.this Parameter
⏱️ 2:33
51.Generic Constraints
⏱️ 2:43
52.typeof Type Operator
⏱️ 2:12
53.Lookup Types
⏱️ 3:12
54.keyof Type Operator
⏱️ 3:55
55.Conditional Types
⏱️ 4:39
56.Contitional Types with Unions and never
⏱️ 3:32
57.infer Keyword and `ReturnType<T>`
⏱️ 3:47
58.Mapped Types
⏱️ 2:48
59.Mapped Type Modifiers
⏱️ 3:37
60.Template Literal Type
⏱️ 4:28
61.Partial<T>
⏱️ 1:27
62.Required<T>
⏱️ 1:36
63.Readonly<T>
⏱️ 1:34
64.Record<K, T>
⏱️ 4:05
65.Project References
⏱️ 4:18
66.undefined vs. optional
⏱️ 2:48
67.satisfies Operator
⏱️ 2:42
68.PropertyKey Type
⏱️ 0:57
69.ThisType<T>
⏱️ 4:11
70.Awaited<T>
⏱️ 4:12
71.String Manipulation Types
⏱️ 3:36
72.Mapped Types as Clauses
⏱️ 4:01
73.Union vs Intersection Mental Model
⏱️ 3:36
74.Enums are Bad
⏱️ 8:11