If you already have a subscription, you can sign in.
Enjoy free content straight from your inbox 💌
00:00
Here we have a type representing a person with a member name of type string and an optional member date of birth of type date. Now within the JavaScript ecosystem, it is common to have a function that asserts that a particular condition is true. So if the condition turns out to be false, it throws an error instead of doing a standard return. Let's look at an example where we might use such a function. Here we are loading the person from a network call. Now if the network call fails our load person utility function returns now,
00:32
and this can be seen in the type inferred for the maybe person variable. So before we try to use this person object, we use our utility assertion function to assert that maybe person is not equal to now. Now, from our understanding of this function, we know that if this function returns, we should be able to access any of the properties off of the person, for example, the name property. However, if we do so, we get a compiler error. If you hover over the error, you can see the TypeScript still thinks that maybe person might be no. Now the reason for this error is
01:04
that TypeScript does not do any implicit assertion checking. However, it does support explicit assertion checking in the form of assertion functions. To specify that a particular function is an assertion function, we need to add a return type annotation of the form asserts some parameter. Here, the parameter we want to assert is called condition. This tells the types strip compiler that this function only returns if the condition parameter is true. Functions with such a return type annotation are called assertion functions.
01:35
Now that TypeScript understands the impact of calling this function, it knows that maybe person not equal to null must have been true and therefore maybe person can only be of type person. In addition to assertion functions that simply assert if a past and parameter is true, you can create an assertion function to indicate that a past in parameter is of a particular type. Here we have a utility function which asserts that a past in parameter is of type date. If the value is an instance of date, it simply returns otherwise. Instead of doing a return, it throw an error.
02:07
Now at this point it is not an assertion function as we haven't added an asserts annotation, but let's demonstrate its intended usage before we add a proper annotation. Now we want to read the date of birth of the person. So we use this assert date function to ensure the date of birth is of type date. Now we know that if this function returns, we should be able to access the date of birth as the type of date, for example, invoke its two iso string method. However, without a proper type annotation, we immediately get a compiler error. And if you hover over the error message, you can see
02:41
that TypeScript still thinks that date of birth can be undefined. The syntax for specifying that a function asserts a particular parameter to be of some type is asserts parameter name is type. Here we are saying that the assert date function only returns if the past in parameter Value is of type date. With this annotation in place, TypeScript successfully narrows the date of birth to be of type date, allowing us to call the two ISO string method. As a final thought, you might have noticed that the syntax for assertion functions is very similar to the syntax
03:15
for user-defined type cards. And you might be wondering when you should use an assertion function and when you should use a user defined type card. Normally in your application code, you would use a user defined type card as you do not want to be throwing errors in your application code. However, when writing application tests, you would use an assertion function as unhandled errors are gracefully reported as a test failure by popular testing frameworks.