Validate Brand Typed Expressions with Custom Type Guards

Tomasz Ducin
InstructorTomasz Ducin
Share this video with your friends

Social Share Links

Send Tweet
Published 6 months ago
Updated 2 months ago

Type Guards are expressions that guarantee the type of a value. In this lesson, we'll create functions that check if the values we pass them are valid types in our system.

A great example here is with emails. Emails are strings with a very specific set of requirements. The type guard checks those requirements and if they pass then TypeScript will refer to that value as an Email instead of a string

[00:00] A slightly better way to verify whether a regular number expression could be treated as money or first and foremost, how can we even create the valid expression of type money is to replace the type assertion and change the as money function into becoming [00:20] a custom type guard. So we're going to include some validation logic into the ismoney function, and this is the main advantage. So in a very simple scenario, we could basically check whether argument is non negative. The whole point is that first, we have to check whether the [00:39] conditions that we have defined are met. So, essentially, what we're going to do is to have a candidate. So there is a number that maybe it is money, maybe not. We'll see. And we're just creating an if statement to check whether this candidate is money or not. [00:59] So before walking into the if statement, all we know about the end to expression is that it is of type number. However, if we walk into the truthy branch of the if statement, then we can see that yes, the conditions have been met. In various cases, this validation logic could be more or less complex. So let's take a look [01:19] at one more example. Our employee entity includes an email property of type string, but we know that not all valid strings are also valid emails. So it's logically kind of incorrect to define that each string could be an email. So for this reason, let's [01:39] create one more type, which is email a certain subtype of a string. And let's create a similar function is email, which is going to verify whether the candidate is a valid email. Only meaningful candidates for emails are obviously strings. And [01:59] let's say that in this case, we're going to use a super complex email regex that we're going to test against our expression. So using this is email type guard, we're going to verify whether an email candidate which is, let's say, [02:19] thomas at duching.dev is going to be a valid email. So if it does pass this reg x expression, which we're going to see right now, we would verify whether this is a valid email or not. What is important and what is [02:38] an additional advantage is that if in our code base, in our memory, we keep the information that something that has already passed the validation is not just a regular string, but it is already an email, then we don't have to redo the validation. Like, we don't have to repeat it over and over [02:58] again because on the type level, we can include the information that yes, this string primitive has already passed this. So our multiple functions or methods that require a certain email, not just a string, but email to be passed, they do not need to repeat the validation. What we [03:18] need now is to create a more convenient way to create our special types for email and money and essentially to create brand types as money is a brand of number and email is a brand of string.