Designing Your Types 11 exercises

Implement a Generic Type

The goal of this challenge is to create a generic type helper that receives one type as input and returns another type as output.

We'll start by creating the DataShape type, which for now will be typed as unknown:

type DataShape = unknown;

We can make DataShape generic by specif

Loading solution


00:00 Okay, so the goal of this exercise is to create a kind of generic type or a type helper that takes in a type as an input and returns another type as an output. We can do that by basically doing something like this. We're going to say type data shape, and we're just going

00:16 to say equals unknown for now. And now this type data shape basically is just like a type. It's just a variable. This is all of the types that we've seen so far are basically just types, non-generic types. We can make it a generic type by specifying a type parameter

00:34 on it. And we open up these angle brackets and then we say T data inside here. We can call this generic type whatever we want, or this type parameter whatever we want, T data just here. And now if we were to declare this, if we were to say example equals data shape,

00:49 it would yell at us because it would say generic type data shape requires one type argument. Well, the way that we can do this, this is just basically like creating a utility type that we've seen in TypeScript before, like record, like promise. And so if you were

01:05 to do the same thing with promise, we will get the same error. Generic type promise requires one type argument. So we need to pass it a type argument. Let's pass it. Let's just try passing it this user shape here. So let's bung that in there. You can pass any type to it, even other name types. And now example, if we hover over it, it's unknown. That's

01:25 because in data shape here, T data, hmm, interesting. It's got unknown on it here. It's just returning unknown. If we return one, two, three from it, then example will be of type one, two, three. But how about if we return T data from it? Well, example is now going to be ID, name,

01:41 and email. So inside here, you can start to see data shape is now a type function. It can actually transform the types here, or it can basically make this shape and reduce a bit of our duplication for us. So what we're going to do is inside here, we're going to

01:58 say, okay, on one branch of this object, we're going to say data is T data. And then on the other branch, we're going to make it error shape just here. So you can start to see now we're sort of copying over some of the logic inside user data shape and just putting it

02:13 inside this data shape here. Lovely. So now example here, we've now got it working. So it's basically this user data shape. So we can actually call this user data shape instead of this down here. And if we look at our test down the bottom, it's still working. If we

02:29 were to change one of these and say like this user data shape is actually ID number, then this would break. But we can see if we go back up to user data shape, bam, working nicely. So now let's do the same with post data shape. Let's grab the actual information that's different

02:44 between them and go into data shape and pass it the type arguments there. And bam, it's now working. And look at this. Look how clean this is. We have a data shape type function, which basically just describes its own behavior up here. We can even add a comment up here

03:01 to say the data shape we get back from the API. And then if we hover over data shape, we can see that's being pulled into the information there. Lovely. So these generic types are a really core way that you can capture reusable behavior inside your application types and

03:20 use it to kind of model your business logic. So this data shape, this isn't a global available in TypeScript. Like we're not going to get this anywhere else. This is just information that we know about our API. This is how it returns its data. And now we can just reuse it again and again and again. And there's a single source of truth for it. Whereas if

03:37 we go back to the problem here, if we needed to change this data shape or something, for some reason it was coming back as like an uppercase data or something like that, then we would need to go in hundreds of different files and modify all of that. Whereas a single source of truth means this data shape gets to capture that reusable behavior in one place.

03:57 Beautiful.