1 00:00:00,210 --> 00:00:04,553 Okay, so in our last video, we wrote our first function with 2 00:00:04,553 --> 00:00:09,990 a parameter type annotation, and even a return type annotation. 3 00:00:09,990 --> 00:00:12,900 In this video, we're going to talk about type narrowing. 4 00:00:13,950 --> 00:00:16,921 I'm going to open the file explorer on the left and 5 00:00:16,921 --> 00:00:19,950 navigate to the functions-in-ts folder. 6 00:00:19,950 --> 00:00:24,138 We'll be continuing from our parameter-annotations file, and 7 00:00:24,138 --> 00:00:29,447 if you don't have this file don't worry, you could download the project folder and 8 00:00:29,447 --> 00:00:32,380 go into the type-annotations-end folder. 9 00:00:33,770 --> 00:00:38,110 This will have a file called parameter-annotations, and 10 00:00:38,110 --> 00:00:42,880 you can go ahead and copy the first seven lines from this file, and 11 00:00:42,880 --> 00:00:46,348 paste it in a brand new file that you can create in 12 00:00:46,348 --> 00:00:53,000 the type-annotations-begin folder, which is what I've got here. Cool. 13 00:00:53,000 --> 00:00:57,610 Let's hide the file explorer on the left, and let's get started. 14 00:00:57,610 --> 00:00:59,878 So, type narrowing is a way for 15 00:00:59,878 --> 00:01:05,130 us to narrow down the exact type of our variable or function parameter. 16 00:01:06,280 --> 00:01:10,750 This is helpful, especially if we're using something like a union type. 17 00:01:10,750 --> 00:01:15,601 In the last video, we created a type alias called numOrString which you 18 00:01:15,601 --> 00:01:17,120 can see on line three. 19 00:01:18,200 --> 00:01:24,540 We added this type alias to our num2 argument in our add function on line five. 20 00:01:24,540 --> 00:01:25,804 And because of that, 21 00:01:25,804 --> 00:01:29,750 we got an error in TypeScript that you can see on line six right now. 22 00:01:31,250 --> 00:01:36,486 Because our union type on line three is a number or a string, TypeScript doesn't 23 00:01:36,486 --> 00:01:41,880 know what type we're going to use on line 6 when we add our two arguments together. 24 00:01:42,980 --> 00:01:47,990 If our num2 argument is a number, then line six should work fine. 25 00:01:47,990 --> 00:01:51,340 But if it's a string, then we should get an error. 26 00:01:51,340 --> 00:01:54,960 We can use type narrowing to tell TypeScript how to deal with that. 27 00:01:56,340 --> 00:01:59,148 First let's get rid of our num3 argument on line five, 28 00:01:59,148 --> 00:02:00,958 because we're not going to use it. 29 00:02:03,936 --> 00:02:07,271 And now let's add an if statement saying, 30 00:02:07,271 --> 00:02:12,285 if num2 has a type of number, then return what we already have. 31 00:02:12,285 --> 00:02:14,143 I'm going to add it above line six. 32 00:02:25,457 --> 00:02:30,450 Below our if statement, we're going to return num1 + num2 33 00:02:30,450 --> 00:02:33,627 as an argument of the number function. 34 00:02:40,609 --> 00:02:45,409 So what this is saying is, if num2 has a type of number, 35 00:02:45,409 --> 00:02:51,146 then return line seven, which is adding both numbers together. 36 00:02:51,146 --> 00:02:57,492 However, if num2 is not a type number, which means there'll be a string, 37 00:02:57,492 --> 00:03:02,370 then convert that string into a number and add it to num1. 38 00:03:03,830 --> 00:03:09,050 If I'm being honest, this isn't exactly good code, because if num2 was a string 39 00:03:09,050 --> 00:03:14,950 that didn't contain a number, we'd get a completely different error from line ten. 40 00:03:14,950 --> 00:03:20,920 But for the purposes of this example, the code I've written is fine. 41 00:03:20,920 --> 00:03:26,210 Okay, so what we've just written is type narrowing in its simplest form. 42 00:03:27,440 --> 00:03:31,935 We're using something called a type guard to say, that if this is a number, 43 00:03:31,935 --> 00:03:33,190 then do this. 44 00:03:33,190 --> 00:03:37,590 And if it's not a number, it must be a string, so do something else. 45 00:03:37,590 --> 00:03:40,343 Imagine a type guard or a guard in programming, 46 00:03:40,343 --> 00:03:45,050 a bit like a security guard standing in front of a club or something. 47 00:03:45,050 --> 00:03:47,740 They check your ID to make sure you're over 18, 48 00:03:47,740 --> 00:03:50,511 which is what the if statement on line six is doing. 49 00:03:50,511 --> 00:03:55,446 And if it is, you get into the club, and that's inside the if statement, 50 00:03:55,446 --> 00:03:57,365 so essentially line seven. 51 00:03:57,365 --> 00:04:01,924 If your ID is fake or you don't have an ID, you get kicked out or 52 00:04:01,924 --> 00:04:06,333 told to go home, which is the return statement on line ten. 53 00:04:06,333 --> 00:04:08,375 I hope that makes sense. 54 00:04:08,375 --> 00:04:12,430 Okay, we're going to try another way of type narrowing. 55 00:04:12,430 --> 00:04:16,519 Let's copy our add function above and rename it to subtract. 56 00:04:21,259 --> 00:04:26,448 Let's change the plus on line 15 to minus, and we're going to give 57 00:04:26,448 --> 00:04:31,644 our num2 argument a type of number but make it an optional argument. 58 00:04:34,894 --> 00:04:40,705 Now on line 14, instead of checking if our num2 argument has a specific type, 59 00:04:40,705 --> 00:04:43,952 let's check if it exists in the first place, 60 00:04:43,952 --> 00:04:47,380 we can replace this whole line with just num2. 61 00:04:48,990 --> 00:04:52,280 This is known as truthiness narrowing. 62 00:04:52,280 --> 00:04:56,110 We're first checking if the argument exists before returning a value. 63 00:04:58,100 --> 00:05:02,665 If the plus sign on line 18 is bothering you, you can go ahead and 64 00:05:02,665 --> 00:05:04,162 change it to a minus. 65 00:05:04,162 --> 00:05:08,133 But for the purposes of illustrating truthiness narrowing, 66 00:05:08,133 --> 00:05:12,802 I don't think it's necessary for me to go ahead and change that. Cool. 67 00:05:12,802 --> 00:05:15,340 Let's try one more way of type narrowing. 68 00:05:16,840 --> 00:05:20,273 For this, we're going to make use of our Employee and 69 00:05:20,273 --> 00:05:23,800 our Manager type aliases from our generics.ts file. 70 00:05:24,820 --> 00:05:29,810 If you don't have that file, or haven't gone through that part of the course, 71 00:05:29,810 --> 00:05:30,784 don't worry. 72 00:05:30,784 --> 00:05:34,736 You can copy those types from the parameter annotations file from 73 00:05:34,736 --> 00:05:38,356 the type-annotations-end folder. 74 00:05:38,356 --> 00:05:40,080 Let's do that now. 75 00:05:40,080 --> 00:05:42,828 I'm going to open the file explorer on the left, and 76 00:05:42,828 --> 00:05:45,790 open our type-annotations-end folder. 77 00:05:45,790 --> 00:05:49,858 I'm going to click on the TypeScript file in that folder, 78 00:05:49,858 --> 00:05:53,189 scroll down, and copy these two type aliases. 79 00:05:55,534 --> 00:06:00,000 I'm going to paste them below our subtract function. 80 00:06:00,000 --> 00:06:05,101 Now, let's create a function called job, that will take an argument 81 00:06:05,101 --> 00:06:10,962 called person which will be a union type of Employee and Manager. 82 00:06:10,962 --> 00:06:16,911 First let's close the file explorer on our left and write the function on line 31. 83 00:06:28,421 --> 00:06:33,021 For this function, type narrowing will be a bit difficult since 84 00:06:33,021 --> 00:06:36,864 the personal argument is a union of two type aliases. 85 00:06:36,864 --> 00:06:39,317 We can try using the in operator that's 86 00:06:39,317 --> 00:06:49,927 already provided by JavaScript, let me show you how. 87 00:06:54,719 --> 00:06:59,615 So, what I've just done on line 31 is to check if the job property 88 00:06:59,615 --> 00:07:03,704 exists in either the Employee or Manager type alias. 89 00:07:03,704 --> 00:07:07,475 If it does exist, then return that property. 90 00:07:08,790 --> 00:07:13,182 If we hover over our Employee and Manager type aliases, 91 00:07:13,182 --> 00:07:19,920 you'll see that the job property exists in Employee, but does not exist in Manager. 92 00:07:21,020 --> 00:07:27,639 Therefore, line 33 will only return if the Employee type alias is used. 93 00:07:27,639 --> 00:07:32,306 If it's the Manager type alias, it won't have the job property, so 94 00:07:32,306 --> 00:07:36,987 we can just return a string that says this person doesn't have a job. 95 00:07:44,588 --> 00:07:47,448 Okay, I think for our beginners course, 96 00:07:47,448 --> 00:07:50,482 this is more than enough on type narrowing. 97 00:07:50,482 --> 00:07:54,457 There are much more ways to do type narrowing than what I've shown in 98 00:07:54,457 --> 00:07:55,230 this video. 99 00:07:55,230 --> 00:07:59,991 But with the examples I've shown, it gives you an understanding of how it works. 100 00:07:59,991 --> 00:08:01,041 In the next video, 101 00:08:01,041 --> 00:08:04,989 we're going to focus on something called a function type expression. 102 00:08:04,989 --> 00:08:09,690 It's similar to our video on parameter type annotations, but a little different.