Production-Grade TypeScript Production-Grade TypeScript

Tuple Types & Recursive Type Aliases

Check out a free preview of the full Production-Grade TypeScript course:
The "Tuple Types & Recursive Type Aliases" Lesson is part of the full, Production-Grade TypeScript course featured in this preview video. Here's what you'd learn in this lesson:

Mike demonstrates TypeScript language features added in versions 4.0 and 4.1. This segment covers tuple types, recursive type aliases, and template type literals.

Get Unlimited Access Now

Transcript from the "Tuple Types & Recursive Type Aliases" Lesson

[00:00:00]
>> Okay, so the next set of TypeScript language features we're going to talk about is a set of improvements around what are called tuple types. So the first of these improvements came in TypeScript 4.0, and it's called variadic tuple types. So let's say that I had a type like this, and we'll say that it's an array starting and ending with a Boolean with something in between.

[00:00:31] So there's our something we're gonna make this generic like, should work for anything. And now we can do Boolean, ...T, oops and then Boolean. So before TypeScript 4.0 you would have been forced to put this ...T as the last element of the array. But now we have the ability to say there's some stuff, could be strings, could be numbers and there is a Boolean at the beginning and a Boolean at the end.

[00:01:01] This may not seem like a big deal but some libraries that you use, like if you use lodash-es, functional programming, collection of utilities or RxJS. This is a pretty huge deal. It makes it much simpler to type certain kinds of functions where, maybe you're piping a bunch of things together.

[00:01:23] Or even something like function bind and function apply, where you have this concept of like a partial application or currying, right? This makes typing that kind of thing where you have some arguments and then maybe begin and end stuff. It's much easier. Next we have labeled tuple types.

[00:01:47] So let's say that, we want a street address again, right? So we have a type, address. And we can define this as let's say a house number. I know that we can have letters and house numbers, but I'm trying to make this interesting. And then, we have a city and a state, And a postal code.

[00:02:14] Let's pretend that's a number as well. Now, we might have a function here called print address. And you might want to say hey, the arguments I take, It's just all of the things that are in an address, in order, right? So, but the problem here is we have a pretty miserable autocomplete experience.

[00:02:43] Look at this, we've got address0, address1, address2. If I'm consuming this, I'm gonna have to jump into this file wherever print address is defined. And I'm gonna have to kinda go on a little detective story to try to investigate what the heck is this thing actually consuming? It's not great.

[00:03:03] So, labelled tuple types are what let us do this. And as soon as we start labelling each of these elements, we must continue labelling them. So you have to have it for all of them. So something like this are still an array, although it kinda looks like the key value pairs we're used to seeing in an object.

[00:03:28] And look how much nicer the autocomplete is now, right? We get that street number, city, state, postal. So I'm a big fan of tuples. I think that for one, especially if you're serializing data, if you're getting an API response, this saves a lot of space. May seem like a small deal in this example, but imagine that you're getting, potentially 50 kiloBytes of JSON.

[00:03:55] For a big app, this is not beyond the realm of possibility. So you can save a lot of space and save a lot of data, which matters to your users as well, particularly in places in the world where you have metered connections and people pay per byte, per kilobyte, per gigabyte.

[00:04:17] This is a more compact way to represent the same data. And in your app, you get the same great experience as if this were an object with property names and values, property names and values, right? You still can have that nice autocomplete regardless. The next category of advancements in the TypeScript language have to do with type aliases and interfaces.

[00:04:41] So if you watched TypeScript 3 Fundamentals, v2 we talked a little bit about how we would type JSON, right? Only certain kinds of values are allowed in JSON. You can't have functions, for example. So we worked, combined the type and an interface, a type alias and an interface, which at the time was the only way to do it.

[00:05:05] In order to create something that describes any allowed JSON value. So I wanna really quickly write out that solution. So we had something like this, type JSON array, Which was, sorry, we did this interface, JSON array extends. It's an array of JSON values, Where JSON value, Was a string or number or Boolean, or no, or JSON array.

[00:05:51] Or I think we had a JSON object that might have looked like this. No, we had one more interface JSON object which had an index signature. And this was our old way of typing JSON. Now, it is convoluted, like crazy and it uses a hack. It, so the only reason this works is because this type alias is evaluated eagerly.

[00:06:26] And as it's parsed, we kinda take note that, we're referring to a JSON array at some point. I expect this to be defined as a thing. Same thing with object and then down here we can kind of define these. So we already, JSON value is already understood, we already know what it is.

[00:06:46] So we're taking advantage of the fact that we can get through this, and sort of put a pin in the task of fleshing out what exactly does it mean to be a JSON array in a JSON object? These combination of these two things that allow us to create effectively a recursive type.

[00:07:06] That would permit us to do something like val is a, we could do like nike, and then address. Oops, sorry, I need a comma there. Address is a Spear Street, right? But if we did, we said wave to Mike. We're gonna say it's gonna object and it'll say, I'm sorry.

[00:07:38] This function that you added there is not allowed. That's not JSON. So I'm just simply showing you nothing up my sleeve. This works. Now, what was added in TypeScript 4.0 was the ability to have recursive type aliases. And what that would let me do here it's only possible in TypeScript 4.0.

[00:08:01] And later soon you continues to work continues to work I can refer to my JSON value array here. And then this JSON object thing I can just peel this thing out, boom. Get rid of my wave thing which is not allowed, and it continues to work. So we can have a recursive type alias meaning this type, JSONValue, in the definition of what it is, it refers to itself, in this case twice.

[00:08:34] This makes it, I mean, we just deleted a bunch of code, which is a good sign. This usually means things are made much simpler. So that is recursive type aliases. We also have recursive conditional types. I'm not gonna get into those too much because it's a very advanced feature and you're unlikely to use it in your app until you get really into the weeds with generics.

[00:08:58] Just wanna make note of that lending in TypeScript 4.1. And it would allow you effectively to do something similar to what we have here, which is in a conditional type, which is the kind of looks like a ternary operator with the question mark and the colon. That type can refer to itself in its own definition.

[00:09:20] I will leave it as an exercise to you to look more into that. If it is relevant to your app, I suspect it, for most of you, it's not something you'll encounter. But you may encounter this. So, template type literals. So you may be familiar with the idea of tagged template literals, which are these backtick strings, right?

[00:09:42] Where we can have this dollar signs, this is how we interpolate values into strings in JavaScript. We can do that when defining type literals. So if I had something like this, corner equals, Top or bottom and left or right. Let's see Swinging chair I'm following my example here properly.

[00:10:34] Let me restart VS code here real quick. Just to make sure I'm not like lagging behind in TypeScript version, and I'm gonna comment the rest of the stuff out in case it's interfering It should work. I know why this is not working. It only works in TypeScript, [LAUGH] 4.1.

[00:11:03] I have a note to myself here. So I'm gonna install that real quick. And we should see as soon as this installs, and as soon as I can switch over to it and I'm gonna switch back. We're not gonna be using the beta here, just because I wanna keep things nice and stable.

[00:11:22] But here we can see, that corner combines these two. So we've got top left, top right, bottom left, bottom right. So anytime that you have sort of a, you have a set of values and you want a type that represents all of the different permutations of x crossed with y, this is a great way to do this.

[00:11:46] There are even words you can add here like capitalize. I think that's one of them. Let's see. Maybe a, Retry with parentheses here. Yeah, that looks like it's parsing it is a different kind of syntax here. To be honest, I haven't used this one much but apparently you can do this.

[00:12:12] So I'm just gonna leave it at that. Unlike where you can capitalize this. You could say, I want the first part of it to be an all caps, like capital TOP, as opposed to it just literally trying all the interpolations here. Again, this is in a beta so it may be that they're still iterating on this.

[00:12:37] But the idea is that you could even modify these string literals like these top and bottom and incorporate that modification into your your permutations there. I'm gonna go back to the regular TypeScript. All right, before I move on, any questions about these changes to type aliases and interfaces?

[00:13:02] And in this case, the literal type here, although this is a very new thing. Although I can see how especially if you're doing like CSS and JS, or if you're building react and you need on click, on hover. You could easily kind of create a nice type that was added on to the beginning of all these things.

[00:13:26] That's where I can see this being most useful.