- Now this video is gonna be the most complex one
when it comes to TypeScript and React,
and that's how you deal with generic components
because oftentimes, you wanna have a component
that can accept generic data
and doing that is a little bit complicated.
So, in this case I have a list,
and the list just takes in an array of items,
and these items can be anything.
In our case, it has an ID of 1 and a name of Kyle.
But you know, it could have an age of, like, 28,
for example, onto here.
It doesn't matter. It's just a random array of items.
All I know that it is an array of items.
And then I have two functions.
One is allowing me to get a key.
So here, I know my ID is unique,
so I'm using that as my key.
It just takes a function which passes in an item
and returns to me what the key for that item will be.
And then the render item again passes in an item
and returns to me some JSX
for rendering out that item inside of a list format.
As you can see here, it's rendering out my list just fine.
We look at the list component here.
We just ignore the type at the top for now.
We can look down here.
We're getting our items,
our getKey function and our renderItem function.
We're looping through all of our items.
We're setting the key by calling getKey,
and we're rendering out the content by calling renderItem.
Now for our type,
I'm not really sure what we should do in this case.
That's why I've left some comments
because I don't know what our item type is.
I know our items are some type of array.
Our getKey takes in some item
and returns to us a React.Key.
And our renderItem again takes in some item
and returns to us a ReactNode, but what is this item?
I could manually type this item.
We'll just come up here and we'll say, "type Item,"
and let's just say ID is a number and name is a string.
And now, if we replace these with that item,
we make sure that this says "Item."
"Item."
You can now see all of our code is working fine,
or at least it looks like it's working fine
until I decide to change this to have some other property.
For example, now I put an age into here
and now, obviously, this is no longer working
'cause it doesn't have just an ID name.
It now has this age property, too.
Essentially, I want my code to be smart enough
to look at what my items are
and just figure everything else out by itself,
and that's where generics come in.
So what we can do is we can
get rid of this item type completely.
And instead, I want this to take in a generic type.
You can call this anything you want.
Common practice, people use the letter T for a generic.
But if I wanted to, I could say
that this is like our ItemType, for example.
I'm just going to call this, yeah,
we'll call it ItemType
so it's a little bit more descriptive.
So, what I can do in here is I can just paste this down.
Instead of saying, "Type,"
we'll just say "Item" just like that.
So now, we have a generic item type.
We don't know what this is. It's just some generic value.
And we want our function here to be able to take in
a generic type.
We'll again call this Item,
and we'll pass this along to here as the generic here.
So now, we've removed all of our errors because
essentially we're saying we have an array of items.
I don't know what the type is. It's just some random type.
My getKey is taking in some item,
and it's returning this key.
And this renderItem is again taking in the same item
and returning to us an actual React element.
Everything is working fine.
And again, the way we set up these generics is our function.
We just put some angle brackets after it
and put in the generic.
We can call this whatever we want, like we could call it T,
and it's going to work just fine.
I called it Item to be a little bit more descriptive.
Same thing here.
We passed along that generic, and up here,
we're accepting a generic and we're just typing everything
based on that generic.
Now inside of our app, what's happening,
which is really cool, is it's automatically inferring.
It's saying, okay, our items we know is of type Item.
It's an array of them.
So, we know that each one of these items
is of that item type.
So now, when I come down here to my item,
you can see it's typed to be an ID: number,
name: string, age: number.
Now, if I remove my age from both of these,
you'll now see this item no longer has that H type.
It's automatically being inferred
by typescripts and all that generic goodness.
Now, sometimes TypeScript may not be smart enough
to infer what your actual type is
so if you need to manually specify
the type of a generic component,
you can do that right after your component name.
Just put your double angle brackets
and put the type that you want to define inside of here.
So, we'll say that our type is going to be an ID,
which is a number and a name, which is a string.
And let's say that it's also gonna have an age,
which is a number.
And if we make that age optional,
now what you'll see is that we're passing along
everything and it's working.
And our item, if we hover over it has that type
that we specified, ID: number, name: string, and an age,
which is either a number or undefined.
So, to real quick recap, the way that you set up a generic
is you need to make sure you specify your function
as a generic function and your props are also going to be
a generic prop type.
And then whatever you have that depends on that generic,
you just pass that along
through the generics everywhere here
so we're using this item type everywhere.
We're not hard coding anything.
And then, when we define our component and actually use it,
whatever we pass in most often is going to be inferred
so we don't even need to specify the actual type.
But if you need to specify the type,
you can do that in line, as well.