-: So let's continue practicing with
these generic types because I know they can be strange
to wrap your head around; In the end they're
really straightforward though.
Let's create an average generic function,
count and print.
Now this function should take some argument, some parameter.
Let's name it element, but the name is really up to you
which should be of a generic type.
Because I really don't care about the type,
at least in certain ways.
So let's say we have one generic type in this function
and our parameter is of that type.
That's, by the way, all the typical for generic types.
If you have a generic function,
then often your parameter will be of that type.
Doesn't have to be, but often
that is how you work with generic functions,
as you will see,
as you get more and more experience with them.
So here we got count and print
with our generic type here,
and element is of that type.
Now what I want to return here
is nienda tuple with two elements where the first element
should be my element itself
and the second element should be a description string.
Maybe we name it count and describe, therefore.
So here I got my description text, and here I'll say
got no value, and I want to use that
if we pass in an element which has no length.
Because my idea with count and describe is that we can
pass in an array or a string, and we get back the amount
of characters or elements in that string or array.
So if we got an empty string or an empty array,
I wanna use got no value, but here if I check
that element dot length is greater than zero,
then I want to set the description text to
got plus element dot length plus elements.
You could be even more specific and check if the length
is equal to one here, and then say got one element,
else if element length is greater than one,
we have description text
equal got plus element length elements
so that we got the plural form right.
Now here, description text is there for the second
element and return here. Now you already see
types of complaints about the length here.
Because it's not clear that element has a length.
So maybe we should make it clear that it does.
We could do so by creating a new interface or a custom type
with the type keyword here and here I'll go for
an interface which I'll name lengthy which in the end
is just guaranteeing that we have an object with
a length property which should yield a number in the end.
And then here we can set a constraint and say
that says T extends lengthy.
So we know whatever we get, we'll have a length property
and an array or a string would have a length property.
Now here, I can console log count and describe
and pass in, let's say, hi there.
Now this works because a string has a length property.
It's not a object.
It's a string, but behind the scenes, Javascript
kind of converts this to a object on the fly
you could say and adds a length property
when we need it. So therefore we can safely
call it like this. Type script in first that here
we return an array with either a string or type T
element in there. Now I want to have a tuple
so I'll be more specific here and set the return type
to be basically an array with exactly two elements
where the first element will be of type T
and the second element will be of type string.
So now I'm just saying that we return a tuple here
where the first element will be, well, any element
of our generic type, and the second element
will be a string.
Now, with that if we save this, is recompiled
without errors and prints hi there, got nine elements
because we got nine characters in there.
We could also call this with an array
where we have sports and cooking,
and now you will see that we got got two elements
as a description text, or with an empty array
of course, in which case, if I save
that we got no value, but we won't be able to call
this, for example, with a number because a number
doesn't have a length property and therefore
this does not work.
So, here again, we got our generic function.
Idea is similar to the function before.
We want to be a bit unspecific about the type of data
we get here. We don't really care if it's
a string, if it's an array, or anything else
which a length property. We just care about
that it does have a length property
and then we want to do something with it
because we rely on the length property
in our code, so we need to guarantee
that we got that, but other than that,
we really have no interest in which type of data
we're getting here. I don't want to lock this down
to a string or to an array, and I don't want
to create a bunch of overloads to handle
all the different possible types.
I also don't want to create a very long union type
here because I might forget types which have
a length property, or if I create my own object
with a length property, I might not allow for it
if I restrict this here to be of type,
string and array or anything like that.
So therefore, I want to be more flexible
and with generic types we can be that,
we don't care about the exact type.
Here, thanks to the constraint, I only care about
the fact that it has a length property.