Loading
Current section: 6. Generics 5 exercises
solution

Constraints

Transcript

00:00 All right. Let's jump into this. So we've got our, first one. We're gonna make a create or get ID. It's a very, simple function that is going to take an item, and, we're gonna call it item, the type item, and it's gonna just return the ID property.

00:16 So the problem is if we don't have this little bit right here, then that, simple generic can't really do much for us because we don't know what this item is. All we know is that, we're accepting an item. But, like, there's nothing in here to say, that that item has an ID. So we'd have to say if, yeah, there we go. Like, that could potentially work, maybe.

00:41 I'm not even gonna bother. Yeah. Oh, yeah. First, we'd have to see, is this thing an object? And then, does it have an ID property?

00:47 All of that, like, nonsense. Instead, we just say, hey. TypeScript. Don't let anybody pass us something that is not an object. So we could say extends object.

00:59 And and then we could say, if ID in item, there we go, that should work, unknown. Oh, yeah. Right. Because we don't actually know what the value is. So then we'd have to say, and, man, what a pain.

01:13 Right? So beyond just saying, hey, only give me objects, we can actually say only objects with this particular shape. And then it's as simple as this. So what that means though is I can't call get ID with hi because hi is not an object that has an ID. I also can't just give it a plain object, with other properties.

01:35 It has to have at least an ID property. It can have extra properties. That's fine. But it has to have an ID property that is a string. There we go.

01:45 So now TypeScript is happy. We're happy. We're get we're able to, within the body of the function, do something useful and interesting with, the item that is given to us, but at the same time constraining how our function can be used, which is exactly what we want because the alternative would be to do some run time checks here to make sure it's right and throw errors. And TypeScript can't really help us much with that. And so now we have to do run time, and now we're doing automated testing.

02:12 And all that stuff is good and important, but it's even better if you're, if you can do it statically without having to run the code and, it says, no. This only accepts these types of objects. So you see how it it's a little liberating to be constrained in this case. So, let's do something similar but a little bit more generic. What if we wanted to have a generic get property?

02:33 So you can get any property you want. So here in, the case here, I wanna get the property off the user called email. And so what this is going to do is I don't wanna be able to just say any property. It needs to be a property that the user actually has. And so we can have actually multiple generics or multiple generic types on this function.

02:56 So it's basically multiple arguments, type arguments to this function. So first is the object type. And, yeah, the AI was suggesting to say, hey. That extends object. I think that's reasonable.

03:09 And then, although, like, you could pass a string or an array or, yeah, like a string and ask for its length or something. So let's let's not do that. We'll just object type. It could be anything. But then the key that they pass to us, that second argument, that needs to extend any of the keys that the object has.

03:27 So, we're, this should give us a union of all of the different, available keys on that object. And when we do that, now we're able to, get that property. And what's cool about this is that, if you look at the generated, type here, we see that the object type is the user, so ID, name, and email. And the, key that we're, passing is the email that is, determined based on the fact that we're passing email right here. And that matches the extension of the key of object type.

04:03 And so, it's the key of object type thing here. We could actually just say string, right here, and then we can pass anything we want to. But by saying, hey. No. It has to extend the key of object type.

04:14 Now we get, type safety here and we say, hey. You can't pass a value for the key that is not a valid, key of the object type. And with that then, we, then know what the object type is for that, parameter name. So this is the parameter that we're passing and the key, and we know that the return type is string. Now let's see if we had, is employed or employee.

04:41 There we go. And then we say is employee. Now, that return type is derived to be a boolean. So the return type is whatever the, the value or or the type of the, key that we're looking for inside that object. So we're looking for is employee.

04:58 Turns out that that key or that value is a boolean and so, that's what we're gonna return. And we could say, like, it it could be a union. It could be all also it could be another object. It could be an array. All of that will be inferred.

05:13 And that's just one of the beautiful things about TypeScript is how those types just kinda flow through your program to get you the result that you're really looking for, which I think is just it's pretty awesome. It really is. Alright. So now we're gonna create a merge function. So this, we want to take these two objects, merge them into a single object.

05:34 We could do this with object spread or there's a built in function called object dot assign that we could use. Instead, we're going to make a function, that handles this for us called merge. This is going to have our left side, which extends an object, so it could be any object, and our right side extends an object. And, then the return value is the intersection of those things, left and right, and then we use object spread to spread that into a new object and that gets us the merged value. So, hopefully, that gave you a pretty good peek into what is possible with the, generic functions and even, generic types and is particularly the extends keyword.

06:16 I think that it's really interesting and, powerful. You don't necessarily use this every single day, but you are definitely going to see the, and use things like this every single day. And you'll also notice that it's, lots of the times it's the functions themselves that are the things that need to be generic, but the consumers of those things don't need to, know anything about the generics that of the functions that they're calling. And so this is where you kinda separate the people who are writing the building blocks from the people who are like using those building blocks. And so if you have a really solid understanding of generics and generic functions, then you will be one of the building block builders and, you can hand these building blocks over to the developers who could be yourself also to use those, in the making of their application.

07:05 And really, the the sign of a really well, typed library or framework is one where the people who are using it don't actually have to do too much with TypeScript. Their code looks pretty much just like JavaScript without worrying about any of the types. So that's really cool and awesome and it's really hard. And some TypeScript can get really, really confusing and complicated and especially, coming down to generics. This is one of the most advanced subjects in TypeScript, but it's super powerful.

07:32 And, I hope that you really enjoyed playing with it. Thank you.