If you already have a subscription, you can sign in.
Enjoy free content straight from your inbox 💌
00:00
In this lesson, we will look at the difference between a generic type for a function versus a non-generic type for a generic function. And if this sounds confusing, then don't worry. It'll become very easy to understand by the end of the story. So let's go. First up, we have a generic type, which we are going to call type A, and you know that it is a generic type because it takes a generic type argument. We call this type T and we can use it on the right hand side of the assignment. For example, here we are pointing to a function such that it's input parameter X is going to be of type T,
00:32
and it's return type is also going to be of type T. Next, we define a type that is actually not generic because it does not take any generic parameters on the left hand side of the assignment. However, this type is pointing to a generic type indicated by the presence of the Type T, and this generic is again used as the parameter and the return type of a simple function. Now, as you mentioned, type A is actually a generic type, which means that if you try to use it in a type position without specifying the generic parameter, you will actually get a compiler error.
01:06
So if you want to use the type A, we actually have to provide the generic argument. For example, here we have instantiated A of type number as well as a of type string. Now, type B on the other hand, is actually not a generic type, which means that we can use it as a type annotation without specifying a type parameter. And in fact, since it doesn't accept a type parameter, if we try to pass one, the type ship compiler will complain and mention the fact that this is actually not a generic type. Now, the best way to truly appreciate the difference between these two types is to use them
01:39
with real code examples. As an example, we have a function that takes a number and returns a number and another function that takes a string and returns a string. Now these functions are actually not generic functions, which means that we cannot use the generic type B to annotate them. In order to annotate the number to number function, we need a type such that it takes the number and returns the number. And this is exactly what we get when we instantiate A with the type parameter of type number. And similarly, for the second function, we need something that takes a string and returns the string, which is exactly what we get when we instantiate A of type string.
02:15
However, what if we actually have a generic function? This identity function is actually generic, as you can see with the presence of T on the right hand side, which means that for any given input of type T, it returns a result of type T. Now the type alias B actually points to a generic type, and therefore no surprise we can actually annotate this as type B. Now, these two type aliases might seem confusing at first, but over time you do develop an intuition for such cases. To recap, type A is generic as indicated by the type parameter present on the left hand side
02:48
of the type definition. And since the type is generic when we use it, we have to provide the generic type argument. However, the resulting type is not actually going to be generic. For example, here We have number two, number or string to string. These are not generic functions. Now the right hand side of type B is actually generic, and therefore you would use it if you have a generic function. And since our identity function is a generic function, we can annotate it using type B. Now to really drive this point home and perhaps make the nature of these two types more obvious, let's create them using interfaces instead of type aliases.
03:24
The interface equivalent for type A will be a generic interface that takes an input type parameter and then has a simple callback signature. The interface equivalent for type B will actually be a non-genetic interface in which the callback signature itself is going to be generic. And I've intentionally named these new types to give you guidance on what they actually are. The first one is a generic interface for a non-genetic function, whereas the second one is a non-genetic interface for a generic function.