Lesson Description
The "Generics" Lesson is part of the full, React and TypeScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:
Steve introduces generics by explaining that they act as placeholders for types in functions, allowing for flexibility in defining linked lists with consistent value types. He demonstrates how generics can be used in functions like tap, where the return value is based on the input type, showcasing their utility in making types more flexible.
Transcript from the "Generics" Lesson
[00:00:00]
>> Steve Kinney: We're going to talk about building some utility types as well as this idea of what's called like a polymorphic component, which sounds very fancy. I promise you it's not that fancy, and that will kind of pull it all together for us. The half topic is I'm going to talk just enough about generics for a minute so that if you know about generics, great, we'll do a quick review.
[00:00:30]
We're going to talk about just enough about generics that if you're like, "I don't know what that syntax is, I just copy and paste it from Stack Overflow," we'll do enough to disambiguate it so that we can talk about the utility types and the other stuff. But like, this is, you know, there is other ink that has been spilled on that topic—just enough so that we can kind of work through it together.
[00:00:55]
Okay, so I am just going to do this in the TypeScript playground. Like I said, it's linked from the page or you can just Google TypeScript playground. And I'm going to biggerize that font a bit. The easiest way to think about what a generic is, is like an argument that you would give a function. This is an argument that you would give a type, right?
[00:01:24]
So like, let's say we're going to build like a linked list, right? We could do something like, type Link is got a value that's a string, and it can then also link to another value that's like that. And so now you can make a linked list where you could say like const first is a Link, and it's got the value of first, and I guess we should make that optional.
[00:02:08]
And we can say const second, it's got a, is a Link, and we could say it's got a value that is second. And then finally we'll say first.next equals second, and it all works. The problem, it's not necessarily a problem, the reality of this code is I now have a linked list. I don't have any way to traverse it or stuff like that, but on a type level, I have a linked list.
[00:02:45]
But my linked list can only be a string as a value, which maybe it's fine. I could say that this could be any or unknown, or it could be like string or number. The interesting thing was like, what if I wanted to have a linked list where every link was at least the same type? I don't care what that type is, but like, the value should be the same for the entire chain, whatever that happens to be, right?
[00:03:18]
So then I need some kind of like effectively like a variable for my types, right? And that's where a generic comes in. So I can actually say that the Link is T and the value is T, and we link to another one of the same type. So like, we do not know what T is right now, but all we know is whatever T is, the next node also should be a Link of the same type.
[00:04:00]
So now I can put in like string here, and I could put string here, and this works. However, if I made this 12, right, well, one, that wouldn't work. And if I made this a number, I can't put it on that chain, right? Because T in this case was a string; here it was a number. It's just a placeholder value, right? And so you saw it before when we did ComponentPropsWithoutRef and I handed it the word button, right?
[00:04:32]
That button was the variable, the generic to say like, "Yo, get me all the types for a button," right? I could have put form in there, I could have put an a tag, I could have put whatever. It's simply like a placeholder, and it's useful a lot in functions because a lot of times a function can basically use the clues to figure it out as well, right?
[00:05:03]
And so like, for instance, if I said, in functional programming, there's like ID and tap. Let's do like tap real quick. So does anyone know what the tap function is? Tap is, I'm going to give you a value and a function. Like, do something with that value and then give me back the original value, right? For a moment, pass it into this function, but I want it back right afterwards, right?
[00:05:37]
So we can say something like tap, and that will take some kind of type. Value is T, and the function is going to be, or fn is going to be some kind of thing of value T returns void, and we'll return back the T. So like, this tap function, value can be basically anything, right? The function is going to assume that the parameter we're passing in is this value, and we promise to give it back at the end.
[00:06:18]
If value is a number, guess what? Number, number, number. If value happens to be a string, string, string, string. If value happens to be a boolean, boolean, boolean, boolean. If it happens to be a giant payload, giant payload, giant payload, giant payload, right? It's just simply a way to make your types more flexible so that I could say, and so now if I say foo is tap and we'll give it a string of wow.
[00:07:07]
So because the first one that basically set what T is, is a string, guess what? We know that the return value is a string. We know that this should be a string. We know that it's a string in here, and like a string comes out the other way. If I turn this into a number, right? Okay, cool. F is a number, value is a number, value is a number. It's simply a placeholder.
[00:07:33]
And what's really cool is if you look at this implementation, you can see that we've been kind of secretly—like, you've seen the angle brackets, it hasn't been a secret—we've been kind of like React uses this technology from TypeScript all over the place, which is useState, you handed it a number, it knew that count was a number, it knew that setCount took a number, right?
[00:08:01]
That's how it did it. And so like, you too can do it for your own kind of utility types or something, which is like, "Hey, it can be anything, but like whatever that placeholder is, it should be consistently that." That way you don't need to write like one for strings and one for numbers and one for buttons and one for whatever. You can also say like for this T, you can say, and you've probably seen this before, extends string or number.
[00:08:33]
So now T can be anything as long as it's a string or a number, right? So it's like, as long as T extends string or number, then you can use it. So if I put like a true in here, that's no good, but like the string true is good, right? And so you see this a lot in utility types, right? There are a bunch of utility types that are built in to TypeScript, super powerful ones, right, that if you just Google TypeScript utility types, there's like one page.
[00:09:31]
I'll show you some of my favorites. If we said const something is, or let's say type Something and we'll just say that this is foo is one or foo is a number, bar is a string, and baz is boolean. Why not? If we said type SomethingElse and we said Pick from Something Foo and Baz, guess what you get? A type that only has those two properties, right?
[00:10:12]
Another fun one is Omit. Does the opposite, right? So if you're like, "Hey, I have this one type that I really like that I need," but like, let's say it's for like submitting a post, right? For submitting a post, you might not have an ID yet, and so you're like, "I want everything about a post except for the ID," right? You could simply put the post in there that we had earlier and then omit ID.
[00:10:40]
The other super powerful one that you use in a React app for like update is another one, like, "Hey, I want an update where I'm going to have some of the properties of a post and those would be the fields that we update," right? In that case, you would maybe use something like Partial, right? That one doesn't take any arguments, right? And now this is all of those properties, but they're all optional, right?
[00:11:21]
The other one that maybe isn't totally React specific, but I find myself reaching for all the time is, there is Parameters and ReturnType. And so let's say you have a function and you just want to get what the return type of that function was, right? In fact, we have one here. We know that it's going to be the string true in this case. So I could do something like type of like, and that can just be ReturnType, and then I go find that function or that component, right?
[00:12:17]
Components or functions. Let's say A is number, B is number, and this will return A plus B, and we'll say a return. Right, the return value is a number, so now you get this. The other one is Parameters, which does what it says on the tin. This one you get A is a number, B is a number, because A is a number and B is a number. So if you have like, "Hey, I have this function, and I need to get like something that matches like the only the parameters of that function or only the first value or something like that," it's kind of hard to come up with fictitious ways, but like, there will be a time in the next three weeks where you're like, "I just need the type of that first thing." And you can even do like Parameters and you can do zero, you'll get the first argument, right?
[00:13:05]
One will get you the second one, so on and so forth. If you do three, you end up with a never or undefined because that's the way it works in JavaScript. And so there's a bunch of these useful ways to kind of navigate this. There's a whole bunch of different ones and you can write some of your own. I'm going to show you, like there's some very complicated TypeScript ones.
[00:13:31]
I will show you some very common React ones that I tend to use, and you can just copy them and use them. I copy and paste them from every project. There are a bunch of useful ones, but they kind of just sit on top of this technology, which is why I felt like five or ten minutes of talking about generics in a React and TypeScript thing was helpful for us.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops