Skip to main content

over 3 years ago Syntax Podcast

TypeScript Fundamentals × Type Narrowing, Guards, and Predicates

Wes Bos

Wes Bos Host

Scott Tolinski

Scott Tolinski Host

Topic 0 10:43

Truthy falsy checks

Wes Bos

in a failure. I had that as a string, accurately guard against potential other types. Exactly. And a very simple type type guard for that will look like If,

Wes Bos

I use a regular function, Before you go ahead and grab that value with an if statement or or we'll talk about how to do that in just a sec.

Scott Tolinski

Annoying. Yes. Annoying is the, the

Wes Bos

there's a couple of solutions. 1, just pass the element into the function, you will it will tell you string or number.

Scott Tolinski

less

Wes Bos

instead of Reaching outside the scope to get it, which is what I would do, I think, typically Yeah. Anyways. Because then your your functions are more pure. Right? Yeah. That's kinda how I roll. Yeah. I I think that's This is probably your best bet. And the other way is you could just use a type of function that is not hoisted, which is

Scott Tolinski

it. But reverse it. Like, if it's a 0 and you put an exclamation point in front of it, that's going to equate to true because the bang is kind of like

Wes Bos

a function expression where you say Const function name equals function, which I don't I usually don't like those, but

Scott Tolinski

agree with that, where you're just like, meh, I had heard the word predicates involved in, like, Converts it to the correct Boolean. Yeah.

Wes Bos

However, TypeScript was saying that's not good enough. And the reason why that was not good enough is because to write a narrow or to check if something is of a specific type, issues with Internet the type from Two possibilities, undefined or a video to 1, which is video element. A media a media element is another good example.

Wes Bos

And a lot of people Our example earlier, it could be our response type could be a success or a failure, All settled results sometimes before you can work with that value, after the filter, I was like, Okay, these are all successful. I could go ahead and access the properties on successful types. And it's like, it's possibly

Scott Tolinski

It's funny to me that a lot of these, in practice, they often feel

Wes Bos

If there's possibility that that could be called before you Yeah. Select the element. So it was like, uh-uh.

Scott Tolinski

other people reading your code, you know? Yeah. Yeah. Because for those of you out there who don't know the the double bang trick just before,

Wes Bos

Yeah. So you have to check inside of the function again.

Wes Bos

I I I always say bang, bang, you're a Boolean, which is basically taking the value and coercing it into it. A true bang bang and your boolean. Yeah. So this truthy falsy one actually bit me a couple days ago, inputted value, Can't guarantee that that value is going to be there. So it will always return to,

Scott Tolinski

it. You do 1 guards, and the predicates.

Wes Bos

because I had I would talk about this error message here because sometimes just an if statement is is not good enough.

Scott Tolinski

bang or exclamation point in front of your variable, which will then turn it into a Boolean, Sounds very healthy.

Scott Tolinski

then go ahead. And what that will do is it will check if it has a value on it, and then you can safely assume after that that it is a specific type. So the next one is just basic straight up JavaScript. By doing just a straight up Truthy or falsy check, which is something that you, you know, you should probably be cognizant of if

Wes Bos

Number of 0 equates to false, so that might not be in your in your cards. You know, one thing you could always do with this is do that double a point trick, which some people hate, some people are fine with. Do do you ever do that, Wes? Yeah. So I have been using double estimation for a couple years, and I I kinda stopped using it because I I understand how truthy, falsity works. Mhmm. And then I made a I made a little TikTok of, like, what is this double? Because you you still see it. I do use Yeah. All over the place. Yeah.

Scott Tolinski

Turning a a Boolean value to its opposite. So then you do a second one in front of it. And what that does is the first one essentially converts it to a Boolean, and the second bang why do I have to do this? But at the See, end of the day again, I think TypeScript is smarter than you in many of these regards, and it's it's just looking out for you. Totally. I I also ran into

Scott Tolinski

a diplomatic word, but, yeah, I I totally,

Wes Bos

Alright. Next 1 we have here. Another way to type guard is using a utility method.

Wes Bos

There's a possibility that there would be an error, but the error would be a empty string, you value doesn't exist on let's say you you get a value from a,

Scott Tolinski

perhaps,

Wes Bos

check if it is undefined or null,

Scott Tolinski

annoying.

Wes Bos

instead of doing just like if, So narrowing,

Wes Bos

So in that case, you would have to explicitly all throughout your your code base just as a nice, handy, reusable function.

Scott Tolinski

Redundant or maybe occasionally

Topic 1 18:47

Predicates return narrowed type

Scott Tolinski

you know, I'm not all knowing or anything. But there are times where I'm like Yeah. It. It feels like you could do a little bit more for me here, TypeScript. That'd be great. Yeah. It's it's funny that

Scott Tolinski

Am I not, like, recognizing that, or is TypeScript just not able to infer With me as always is Wes,

Scott Tolinski

for a full archive of all of our shows. And don't forget to subscribe in your podcast player

Scott Tolinski

And it sounds super health, Super handy.

Scott Tolinski

is it me

Wes Bos

Sick. Peace.

Scott Tolinski

Or is it TypeScript in this regard? Like, am I doing something that is inherently

Wes Bos

There's a possibility.

Wes Bos

If you have an array of,

Wes Bos

And then then you can if you hover over it before the function, I had is a couple I don't know. 6 months ago, I was trying to filter a list of

Scott Tolinski

what exactly things are? And and I I often lean on it being my fault because,

Wes Bos

that TypeGuard

Wes Bos

No. It sounds super, yeah, super handy. It it's one of those things where you don't necessarily

Scott Tolinski

I I do often

Scott Tolinski

Or drop a review if you like this show.

Wes Bos

Need it until you need it. So, like, I was the only reason or or error returned A query selector.

Scott Tolinski

that Predicate. It will say success. I've never used this before ever.

Wes Bos

So you have to explicitly And and where I've run into this a lot is You would think TypeScript would would narrow the type for you there, but it doesn't.

Wes Bos

And then I was like, okay. It you have to explicitly use a predicate here because I I bet TypeScript will fix this at some point because it should be able to infer So narrowing would be say, okay. If it's a string, then to, response dot error because that would not be because there could be an error. But if it's an empty string, it would say there is no error, but it technically is an error. You know? So I was like, oh, that's that's a good one. I didn't wouldn't even have thought of that, and that's why you use TypeScript. Yeah.

Wes Bos

on GitHub being, like, there's a bug in TypeScript,

Scott Tolinski

unsafe here, and am I

Scott Tolinski

There's tons. There's I think some things around type guards explicitly

Wes Bos

That that's a great I love that. Cool. Alright. That's, that is type narrowing, type guards, and type predicates in TypeScript. Hopefully, you Understand a thing or two about it.

Scott Tolinski

are like times where I feel like,

Scott Tolinski

Yeah. Your first inclination is, like, oh, yeah. There's something wrong with TypeScript here. And it is funny that, you know, it is almost not. It's almost never that way. Yeah. Not to say it won't be, but, you know, it's usually you. Yeah. It's usually you.

Wes Bos

it will say success or failure. You hover over it after wide to narrow. A type guard is the actual code you write

Scott Tolinski

It. It it is so interesting to me because, like

Scott Tolinski

yeah. A lot of these

Wes Bos

And then you can go ahead and use that function, And it it sometimes is weird. It's like, oh, why didn't TypeScript catch it in that case? If you wanna get the video with, you need to narrow from video or audio to

Wes Bos

an error or a failure. I was like, what? And you say, like, that that's, those aren't hoisted like regular functions.

Scott Tolinski

It's not TypeScript. It's you. That's a T shirt.

Wes Bos

Peace.

Topic 2 08:20

Type guards do the narrowing

Wes Bos

before that if, I guess you just got to think about

Scott Tolinski

you know, it's a pretty standard JavaScript thing, but this is often used to make sure that Everything has different properties and methods on it. So being able to say, if blank is type of thing,

Scott Tolinski

you advance on into the next stage of things. You know?

Scott Tolinski

it. What you're doing in an if statement is the type of the thing that you're expecting before

Wes Bos

Then go ahead. And and at that point, if you hover over the variables, an API, and it is either going to be a string or a number. You just basically say, if my value, You have to figure out okay.

Wes Bos

to do that narrowing for you, and there's many different ways to, for you. Right? But it doesn't. Right? Yeah.

Wes Bos

the name for how to narrow something. So narrowing is just the idea of going from

Scott Tolinski

Then you're able to Tends to know better than you in terms of what you're actually checking for. So type guarding, like or type narrowing Head on over to syntax.fm

Wes Bos

type of string, define a type predicate with one of these is properties. You can do them in in line as well. You don't have to make a separate function.

Wes Bos

A type guard is which would not would not be a safe enough type guard.

Wes Bos

and the there's here and there, there's different values. You wanna grab the first one there? It. Yeah. The first one is a type of, which,

Topic 3 06:26

Narrow type from multiple to one option

Scott Tolinski

And so oftentimes, the 1st time that people pick up

Scott Tolinski

type narrowing in general is to,

Scott Tolinski

And type guarding.

Scott Tolinski

You you're really like, okay. This thing is of this type. I know it is. And then in comes the the TypeScript

Scott Tolinski

Checker to say, hey. This property

Wes Bos

what a specific type actually is. Exactly. And if you you often will get this error, Figure out if you are using it before it's defined. You know, like, it should be able to do that. But I don't know. Yeah.

Scott Tolinski

It's so funny these things,

Scott Tolinski

might not be on this type. And and you're thinking to yourself, wait a second.

Scott Tolinski

but TypeScript is telling me that the data potentially isn't there.

Wes Bos

On failure, so and there's a there's a slim possibility

Wes Bos

You generally, the last one in there says, We'll tell you. Okay. In my case, we're talking about grabbing a value which only exists on success, not on error. And it will tell But I was checking if there was an error.

Scott Tolinski

write code that ends up being, Like, what you might think of as being solid or secure code in a way, but ultimately isn't because TypeScript

Wes Bos

that this thing might be a failure. So you need to handle that

Scott Tolinski

blend together in my mind a lot. They really come into play when you're trying to Really narrow down

Wes Bos

it. If you try to access a property on a value and it says property

Topic 4 00:00

Transcript

Scott Tolinski

CSD. Well, come to syntax.

Wes Bos

a type in TypeScript, if you've never used TypeScript Before is sort of a way to describe the shape of Next 1 we have here is check if a property on that type exists. So, basically, all of these type guards In in my case, it will take in a response or a success or failure. Mhmm. And it will return,

Scott Tolinski

it. Incredibly ready to rock here. I could get my video going. Yeah.

Wes Bos

Because I've always just called it, like,

Wes Bos

they're not different things. They are all part of

Wes Bos

The part where your return is is called a predicate. So we'll get into that.

Wes Bos

Which is a string. And we have a value, which in my case, I'm just gonna say it's a number. Right? It could be any type. And then we also have a failure type, which has a message. So the message could be it it didn't work. And then we have an actual error, which will give us more information about when or what went wrong.

Announcer

the tastiest web development treats coming again hot. Here is Wes Barracuda

Scott Tolinski

type guards, and type predicates.

Scott Tolinski

The those are all similar topics. I I I take it because I I know what Tight narrowing and type,

Wes Bos

We've had a hell of a morning. We we both had, like, we both had, like, probably 3 independent I like to use this as a whenever I'm doing, like, a fetch request or something like that, you have a response type. And the response can be Either a success you have to

Announcer

Boss and Scott

Scott Tolinski

And his video now, which is just Yeah. Now all of the sudden my video has just died. After all of that, we were just like, alright. We're good. We're good to go. And now My video has died, so, well, I'll get that back online. You know what? It's time for it's time for Christmas holidays. Yeah. It's I just got a notification from you that says I'm gonna restart my routers,

Wes Bos

a type guard in TypeScript, and I looked it up in the docs. And it's it's says said just use Boolean. Like, if you just use capital b, Boolean and pass The value, it's much more readable. And I was like, I don't know why I really didn't think of that. It does track. Yeah. Yeah. Yeah. So I it's it's a little bit more. I guess people don't like it because it's like bang bang. Yeah. But I understand how it works. So, let's say you have a property on an object.

Announcer

Open wide dev fans, get ready to stuff your face with JavaScript, CSS, node modules, barbecue tips, get workflows, breakdancing, soft skill, web development, the hastiest, the craziest,

Wes Bos

audio and street video streaming. Technical issues. It's just, like, literally I had a problem with my camera and my audio, and Scott had a problem with his Internet switch value

Announcer

Monday. Monday. Monday.

Wes Bos

type narrowing, type guards, and type predicates, which is it. Funny. The 1st time we tried to record this, Scott was like, I don't think I've ever used the word predicates in my life. And I was like, I literally just Googled that What does predicate actually mean? number dot Is number. Well, that's actually not a method in JavaScript, but you could you could make that. You could go on NPM and and grab a a utility method.

Scott Tolinski

it. The Tony Hawk of TypeScript

Scott Tolinski

English, but never within TypeScript or within programming, so to say. So yeah. No. I'm I'm I'm ready for this. It. Let's talk about it. Type narrowing,

Scott Tolinski

We're gonna be talking about TypeScript again. We love talking about TypeScript over here. We're gonna be talking about fundamentals in TypeScript, it. Some lesser known but important features, things like type narrowing,

Wes Bos

That was 15 minutes ago. Something is going on with the Internet today. We are ready for Christmas, but this is this is one of the last ones we need to record. And it's kind of an exciting one. It's about TypeScript fundamentals,

Wes Bos

narrowing types. So let's talk about that. So for this podcast, we have an example that is going to be helpful for you to visualize it. So, types, you have an array of responses When you select something off the page, TypeScript can't,

Scott Tolinski

boss.

Wes Bos

You're ready to rock there, Scott? I am so

Scott Tolinski

On this Monday hasty treat, you know, values that can equate to falsie that aren't truthy truth or falsie values, like things like a number. Right? Like a number of 0.

Topic 5 15:20

Custom utility methods for checking type

Wes Bos

You could use an is error method that specifically checks for it or is is not a number. So that's that's there's one there. And then the last 1 we have here is use an if else a statement. If else statements will narrow for you.

Topic 6 04:12

Narrowing from wide to specific type

Wes Bos

go ahead and do string things with it. If it's a number, then go ahead and do number things with it.

Scott Tolinski

on. Come on. What's going on here? healthy. It sounds I feel like I know what this thing is,

Wes Bos

So a if you have a type of number or string or you have a function that takes in a number or a string, And wide,

Wes Bos

in making it more specific.

Wes Bos

and we need to narrow that down Before we work with the specific success data or the error error, we need to narrow that down. Mhmm. I I just keep using my hands here. I'm saying narrow down. I'm I'm making my hands go Utility functions, all of those things that we just talked about, those are type guards.

Wes Bos

value? So if that is the case, then you have to use what's called a type predicate.

Scott Tolinski

too narrow. You kinda look like the the visual to give folks a visual here, he's kinda doing the gesture of, like, Come

Topic 7 09:47

typeof checks type

Wes Bos

assume that this will always be a string.

Wes Bos

you are used to checking. Yeah.

Wes Bos

And then after that, if it will tell you it is just a string. And that is TypeScript narrowing the type for you and saying, okay. You are now in a a place where you can Humanating union. We'll talk about that in a little bit. It's not really what we're we're trying to focus on today.

Topic 8 05:23

querySelector can return undefined or element

Wes Bos

do things on that video element, like So,

Wes Bos

Sometimes I write code that will take in either a video or an audio tag because those things are very much the same. However, there's a couple properties on either of them that are not shared between the 2. And if you wanna work with it, like dot video width is one of them.

Wes Bos

grab the the width and height. You need to check that that value is actually there. That is narrowing

Wes Bos

narrowing means

Scott Tolinski

us. Checking if something is of a specific type. Yeah. And this type of, thing directly comes about you know, when you're getting into TypeScript, oftentimes,

Wes Bos

HTML video element or undefined.

Topic 9 15:43

If/else narrows types

Wes Bos

it knows the possibility

Wes Bos

So you say I was like, oh, this is a bug in TypeScript For sure. And I looked it up, and I found all these I have all these GitHub threads, x or property value does not exist on type, And it will give you the list of types. And if you scroll down that list, response type in TypeScript. So you don't put colon boolean after the function definition. You put Colon just video. So, basically, because often it they're kind of indented.

Wes Bos

And then you could you could have 1 more else in there, and it will know. Okay. Well, at this point in time, I've narrowed the type down to just be e u r, Those are your type cards, but putting them into a function, Another thing with this the other day, type guard, which was,

Wes Bos

I always use currency.

Wes Bos

Currency could be CAD or US or So the the solution to that was are going to be just regular JavaScript

Wes Bos

Then do this thing. And then on the next else if, comfortably promise Hey. Hey.

Wes Bos

You can say if currency equals CAD,

Wes Bos

of currency is not gonna be CAD because you're a check for it. It's the last 2.

Wes Bos

or EUR.

Wes Bos

at that point, the same thing with switch statements. They work exactly the same way. So next step is type predicates,

Topic 10 16:22

Predicates explicitly narrow types

Wes Bos

response is success.

Wes Bos

Those type guards need to explicitly state that you are narrowing the type, On it that will say the request was successful or got 8 users or something like that. And then we have a value on there. So we have a message, set the volume, set the source,

Wes Bos

is Simply running a dot filter and checking for a successful Mhmm. Which promise all settled will return rejected promises and resolved promises. And I was trying to filter them just for the resolved promises.

Wes Bos

success, meaning that you say the argument to this function An element or no just to an element. Right? However, I wrote a function underneath that on the 3rd line. But because functions are hoisted, response And all of them are like, uh-uh. It's hoisted.

Wes Bos

which is type of, if statements,

Wes Bos

returning whether or not something is of a type. And that is All the type predicate saying It's technically called the whether or not that thing is Like, if if someone were to tell you, alright. We'll check if this thing is has a specific property or check if this thing looks like this. You there's There's many different ways that you can do that, and you probably have written those things a 1000000 times in JavaScript. So type of is one of them. Next one is check if a property exists on a given type, type guards are. Yes. Yes. So predicates is is just pretty much part of that. All of this stuff today, they're not, We'll catch you on Wednesday.

Wes Bos

is specifically specific

Wes Bos

is of a specific type. And what what that does is

Wes Bos

and then the return type And often,

Wes Bos

Or sometimes you just simply want to take all of the type guards that we just talked about and put them into a nice reusable function that you can use throughout your entire code base, like is error or is success response.

Wes Bos

Of that. Or let's talk about the body of the function first. So the body of the function is all of the type cards we just talked about. Response that has own property or response that,

Wes Bos

we just talked about ways to type guard, And before you go ahead and

Scott Tolinski

and The note here is that type predicates use the is keyword to narrow. Now I'm super interested in what a predicate here is in this regard and what exactly this means. Yeah. So,

Wes Bos

of a specific type. It will narrow it down for you. So in in my case, We have a function called is success. It takes in a success or failure, or in our case, we are gonna take in a response, narrowing is the process of Taking a type that has a few possible options or a type that is sort of wide,

Wes Bos

message is equal to success or whatever the way whatever way you're going to try to figure out if something is of a specific type.

Wes Bos

So those are just functions that take in a wide type.

Topic 11 03:41

Response types success or failure

Wes Bos

is just a list of 2 types, a success type or a failure type.

Wes Bos

or a failure. And and that is what's referred to as a union. Basically saying it's one thing or another thing. It's a list of it. Of possible types. A response type and you want to filter only for successful responses. You wanna take all the failures out. Mhmm.

Wes Bos

Then, TypeScript. Of course, you return a Boolean, but TypeScript knows that this function and I I basically selected something off of the page and the line underneath it, I checked if it was there. So I would narrow it down from But, like, also, like, that with that hoisted example, like, couldn't that

Topic 12 10:13

Check if property exists on type

Wes Bos

if the response has own property value, And those are just yeah.

Wes Bos

has own properties is what I've been using a lot. So you grab it Bro. It's not enough. Yeah. Which is odd. Yeah.

Share

Empowering developers for over 286197055542 milliseconds!