Check out a free preview of the full TypeScript 5+ Fundamentals, v4 course

The "Type Alias" Lesson is part of the full, TypeScript 5+ Fundamentals, v4 course featured in this preview video. Here's what you'd learn in this lesson:

Mike explains the concept of interfaces and type aliases in TypeScript. How type aliases can be used to give names to types and simplify complex type definitions, how type aliases can be used in place of literal types, and how they can be extended using intersection types are also demonstrated in this segment.


Transcript from the "Type Alias" Lesson

>> Next, we're gonna talk about interfaces and type aliases. These are both mechanisms that TypeScript allows us to use to give names to our types. And to pass them across module boundaries using imports and exports, similar to how we treat values in JavaScript modules. The first concept we're gonna discuss is called the type alias.

So if you think back to this syntax that we used for the object in our success tuple case, it gets noisy and complicated. If we use this all over the place, if we just look back at that function real quick, I actually made it look a little bit simpler here.

But look at this return type, this is just a lot of noisy syntax. Imagine you have five or six functions that deal with this type, and you have this written in your code, like this. I just doubled the cognitive burden here by writing this type explicitly. And then imagine you have a whole library dealing with user info, and it's kind of all over the place.

So what we want to do is give this type a name, and type aliases help us do that. So, we can define a name for the type, we can define the shape of a type in a single place. Similar to how you could have a class in your JavaScript code base that you use in a bunch of different places.

But there's only one place where it's defined. That is strictly not the case when we're doing this. It's almost like instead of defining a class, you have object literals with methods on the object. And you're using those all over the place, you have no central definition for those.

It'd be very easy for them to sort of drift apart at different call sites. So we wanna have a central place where this is defined. And, of course, we want the benefits of import and export. I'm gonna open the equivalent code snippet in our editor here. So let's say that we have something that represents an amount, right?

We've got a currency type and a value, so you could say like 300 Canadian dollars, something like that. And let's say we wanted to define a function called printAmount. Well, what we've done here is we've created a type alias. So we're saying typeAmount =, and then look at the right side of this.

It's definitely a type, right? There are no commas here. This is a string, like string and number, these are types, they are not values. This is one of the only times you will see type information on the right side of an assignment. And this is something that will completely melt away as part of the compile process.

This will get erased from your code, not your source code, but when you do your build, this will just completely disappear. Because we've defined this and we've given it a name, look at this, we can use it in place of what would have been a literal type like this.

So instead of doing this, we can just say, that's amount. We could use this in a bunch of different places. You can, of course, export it, import it, as we'll see later. So here I've got an object I'm creating called donation, and it's valid. So there's no need that I say this is an amount, it must be an amount.

It's literally just a shorthand for an explicitly defined type, there's no other formality to it. Is asking what are the differences between types of interfaces. I promise we will get to that, that is in this section, we will get there. So, a type alias, here's one difference with interfaces.

A type alias can hold any type that you're able to define in TypeScript. So we could say, Something like that, MightBeNull, string might be null. You can put whatever you want here, that's not the case for interfaces, as we'll see later. But that is one of the great powers of a type alias.

If it's a type, you can give it a name. And then you can import and export. So if we look at the example from last chapter where we're flipping a coin. And we've got this maybeGetUserInfo thing, and I've got in all its full glory, there's your return type.

It's just a lot of syntax here, right? Lots of square brackets, lots of braces, it kind of makes you cross your eyes a little bit. So there's our flipCoin, it's heads or tails. And then maybeGetUserInfo, there's its return type. So if we were to model the return type as a type alias, We could do it like this, create a tuple type, right?

UserInfoOutcomeError, UserInfoOutcomeSuccess. Then we could union those types together. And the tooltips get much nicer. You have words that can explain what the meaning of this thing is. It's a little bit like we're no longer telling someone how to build a watch, we're telling them what time it is.

We're giving these types a semantic meaning, as opposed to just spitting out the contents of the structure that we're looking for. Just like variable names, right? Variables have a name, and you can write it in such a way that it conveys the purpose of this thing. Now you can do that for types as well.

Just think of it like a variable for types. So let's talk a little bit how we can work with these type aliases. And I'm calling it inheritance for type aliases. It's not really inheritance, but it's sort of how do you build type aliases based on other type aliases.

And you do that with an intersection type. So here's an example where we have, let's say, we have a library that makes every JavaScript date, gives it a method on it called getDescription. So all dates can have descriptions now. So we could say, all right, well, this is a special date.

And sorry, to be clear, not all dates would have descriptions. We're creating a special date type for those that have descriptions. So we would say, all right, I want everything that's on the date type. And I also want to add a method to it, getDescription, which returns a string.

And here we can actually create a SpecialDate, right? We're gonna create a new Date, and we're gonna add a method to it like this. And look at this, we've got newYearsEve, it's a SpecialDate, so the tooltip just got pretty clean. And here, look, I've got all of the Date functions, but there's getDescription, but getFullYear is still there as well.

These are things that are available on a conventional Date. So if you wanna think about this kind of like inheritance, where we can say, all right, I have a type alias, I want to make another type alias that's a subtype of it. This is a subtype of a Date, it can pass as a Date.

If you need me to give you a Date, and I hand you this, you'll be totally happy. It has getFullYear, it has valueOf, it can create an ISO 8601 string. But it's also got some other stuff. This is actually a more specific type of Date, cuz it has this extra requirement.

The getDescription method must be on it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now