If you already have a subscription, you can sign in.
Enjoy free content straight from your inbox 💌
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.