This course has been updated! We now recommend you take the TypeScript Fundamentals, v3 course.
Transcript from the "Generics" Lesson
>> Mike North: So let's dig into generics. Generics parameterize types in the same way that functions parameterize values. So we're gonna talk about when it's appropriate to use a generic. The ins and outs of type parameters in general. And how to constraint type parameters, for example, within a function, you have what you need in order to have type safety within the function, and the outside world is happy with things as well.
[00:00:35] Cuz types are just constraints and they represent contracts between various entities.
[00:01:12] We can put whatever we want there, and the function allows us to reuse this piece of code, whether we want to wrap a string, or a number, or have a wrapped value inside a wrapped value, the perimeter x is sort of a placeholder that is used. And it allows to reuse this piece of code.
[00:01:32] Similarly, we can create a type that allows us to provide a type parameter in this case X in between these angle brackets. And that type parameter will be used as the type for this property value. So here's an example, if I pass in string array, this is just like passing an argument to a function, right?
[00:02:00] But I'm passing a type to a generic type.
>> Mike North: So because of the tool tips like,
>> Mike North: This is correct, but I'm more interested in what I can do with this thing. If we look at val.value, we can see that it is a string array.
>> Mike North: As you can see right over here.
>> Mike North: If we were to change this and make it just a string, well, we would get a type error here, we'd have to make this a string.
>> Mike North: And now, the type of value is string. Sorry, it keeps disappearing, I'm being overzealous with my mouse. But hopefully you can see here, we're we're sort of filling in a blank or providing a type that is then incorporated into what WrappedValue shakes out to be.
>> Mike North: So you can name these type parameters whatever you want. I can make this,
>> Mike North: Name function keys.
>> Mike North: I can make it FrontEndMasters, just like you can name function params whatever you want. That's completely a local name to everything that has access to this type param, which is just sort of, think of it like the same idea as a closure.
[00:03:29] Right, you have a scope, and this is a local variable, it's almost like an argument passed to a function. The name of that argument only has meaning within that function.
>> Mike North: So the convention, which you'll see a lot, is to start with the capital letter T, and use capital letters like T, U, V, or S, or R.
[00:03:53] This a carryover from C++ which uses template parameters which basically they're conceptually identical to this. So that's why you'll see a lot of TypeScript coding, including my examples, they'll just use the capital letter T. But that's just like saying this function takes x and y as arguments, and we can name this whatever we want.
>> Mike North: So if we were using something like array filter, we could type a function that would appropriately filter based on the types of things that might be in this array, right? If we were filtering through an array of strings, so that we could remove any empty string we found, we'd want to accept as our filtering function, we'd want that to take a string as an argument and to return a boolean.
[00:04:47] And in fact, that is what happens, if we had an array containing strings, .filter(),
>> Mike North: And we start to implement our callback,
>> Mike North: Let's say it's a filter that always passes, it turns out x has a value of a string.
>> Mike North: Right? That's just what we want. If we had a named function that was designed to,
>> Mike North: Named function like this,
>> Mike North: That only wanted to receive numbers, we would absolutely want this to say, there's a misalignment here. Your function's designed to take numbers, I need one that's designed to take strings. So this would be an appropriate type using a generic that would allow us to sort of fill in the blank, what is the type of the entity you're filtering for?
>> Mike North: So here's an example of us using this generic type of passing in string as the type parameter, so this T will turn into a string. And we can see that now, val is a string, and we're checking to see if the type of val is a string.
[00:05:55] This all looks great to me, right? The runtime stuff, this, sorry, that runtime stuff looks exactly like what I would want to check if there's a string or not, and this in fact should be a string.
>> Mike North: If we try to parse in the wrong argument, obviously we get an error, otherwise if it's the right type, we get OK.