In this video I wanted to share a quick TypeScript tip with you. And that tip is that you can create interfaces based off of classes.
Here in front of me I have some code from a game I’m working on.
Don’t worry about the details just focus on line 410 where we have interface ShapeGenerator extending Generator.
Nothing too exciting there if you’ve already seen my video on interfaces, but if we jump to the definition of Generator… You’ll see that it’s a class and not an interface!
It turns out that TypeScript will let you create interfaces from classes, and it does this in an intuitive way: All the public class fields and methods become part of your interface. And then, of course, you can add more if you need them.
Now, why would you want to create an interface in this way?
Well, for this program in particular, I have a number of classes that are based on Generator, but they are all completely separate in their implementation. However, some of them share these three fields, and I want to be able to do things like create arrays of ShapeGenerators.
Create a new interface based off of the Generator class is a super easy way of making it so that I don’t have to repeat all the fields of Generator, and I don’t have to add any extra levels of inheritance just to be able to treat all my similar classes in similar ways.
You won’t need it all the time, but in cases like this, it’s helpful to know that this feature is there.
That’s it for now.
If you want to dive deeper into TypeScript, I’m working on a course called Learn TypeScript by Example. You can find it at https://typescriptbyexample.com/ If you scroll down to the bottom you can put in your email address and I’ll let you know when the course is released.
Thank you so much for watching! I will see you in the next video.
Hello, everybody! In our past videos we’ve talked about the most basic types in TypeScript, today I wanted to talk about enumerations (which you might also know as enums).
If you’re familiar with enumerations from other languages like C, C++, or any other language, they’re very similar in TypeScript, though there are a few differences that you’ll see as we go over their various features.
If you’re unfamiliar with enumerations (or if you don’t use them very often) the easiest way to think of them is as a group of related constants that are important to your program.
What this means in practice is that while you’re writing code you might find some mathematical constants that you need to use, or you might find that some piece of your code can be in several distinct states, and you need to represent that in some way.
Say if you’re writing a game, an enemy might be sleeping, or it might be patrolling, or it might be fighting, and you need to represent those different states with some sort of value. The exact value doesn’t necessarily matter, the most important thing is that you can tell each state apart from the other states. This is a great place to use an enum.
Using that example of an enemy in a game, we’re going to create a simple enum called EnemyState.
You can do that by using the enum keyword, then the name of the enum (EnemyState in this case), and then listing the names separated by commas within curly brackets.
A common convention when creating enums is for the members of the enum to be all upper case, with multiple words separated by underscores. However, there’s nothing forcing you to do that. If you perfer some other way of naming them, feel free to do so.
I mentioned moments ago that enums store constants, but I didn’t actually mention any values here, just names. So what value is used for EnemyState.SLEEPING?
Well, let’s create a variable storing that value, and then we’ll console.log() it.
I’ll open a terminal here and run it.
And we get 0! Okay, so we know TypeScript selected 0 for the value of SLEEPING.
Let’s change it to PATROLLING and see what it logs.
And we get 1!
So you can see that if we don’t specify any exact value, TypeScript will automatically use 0 as the starting number, and then work its way up one by one to 1, 2, 3 and so on.
One thing that’s helpful as well is that this EnemyState enum exists as an object at run time.
So, if you’re debugging something or you’re are working with a library that defines an enum and you’re asking yourself “hey what are the valid values of this particular enumeration?” you can simply log the enum object and see the possibilities.
You can see here when we logged it, though, we got more than just a list of values. We can see that the EnemyState enum maps between both the names and the values in both directions.
So if we had some random variable that came from an enum, and we wanted to see a human-readable version of the value, we can simply do EnemyState[x] and get the name of that member of the enum as a string.
If we open up the compiled .js file, you can see how they do this.
This might be a little weird to read at first, because they’re using a trick to save space, but read it from the inside out and it should make a little more sense.
Here they’re mapping between the name of the value and the value itself. And then it turns out that when you set something equal to something else, you can use that as an expression that returns the value that just got assigned. So they’re mapping the value back to the name, just like we saw in our tests previously.
It’s helpful to know at this point that you don’t need to let TypeScript automatically choose the numbers for you. You can add an equals sign to one of the members of the enum, and then all the values that follow will increment from there. You can also specify each value explicitly if that makes more sense for your program.
Now, let’s pause for a moment and compare enums to their alternatives.
The first and most obvious alternative would be to just declare a bunch of constants as normal variables, rather than as an enum. If you’ve only got a couple constants, or if none of the constants are related, that works just fine. But if they’re related, or you’ve got a situation like EnemyState where your main goal is to simply have a few distinct values, enums are the appropriate choice.
The second alternative, which you may have seen in a prior video, is union types.
As a refresher, a union type is a list of different types separated by the pipe character. You can then assign your variable to any of the types that are listed.
This is very much like an enum, and you’ll frequently see them used like enums in TypeScript code.
Enums have two main advantages over union types: First, since it’s all just numbers behind the scenes, they will be more efficient in some cases. Second, enums are available at run time as we’ve shown previously, so if you need a list of all possible values for debugging or display purposes, enums are a great option.
However, union types are quick to write and sometimes easier to think about, so often TypeScript code you see in the wild will prefer them over enums. Which is best to use will depend on your specific use case and your own personal preferences.
There’s a couple less-used features of enums that I wanted to show you before we wrap up.
First, your enums aren’t just restricted to numerical values, you can also put strings in them.
Back in the TypeScript code, you’ll see that if I remove one of the strings TypeScript gives me an error. Unlike numbers where TypeScript can just take whatever you did last and add a plus one to it, TypeScript has no idea what the next string is going to be. So, if you specify string constants you’re going to need to spell them all out.
Enums with strings in them aren’t used very often, but it’s a feature that’s available to you if you’ve got some string constants you need to group together.
The final feature I wanted to talk about are what’s called “const enums”. You can create one by simply putting the “const” keyword at the start of your enum declaration.
This will result in slightly more efficient code, at the cost of being harder to debug should you ever need to. Again, this is something you won’t see used very often, but it’s another tool to add to your toolbelt.
So that’s all there is to enums! I hope you enjoyed this video! If you would like to go deeper into TypeScript I’m producing a course called TypeScript By Example and you can find that at https://typescriptbyexample.com If you scroll down to the bottom you can put in your email address to be notified when the course is released.
Thank you so much for watching! I’ll see you in the next video.
You can vote on what the next video series will be.
So if you vote I will know what YOU want, now you need to know what I
want for the next series to happen.
I’ve had well over 1,000 unique viewers of this video series, so I
need you viewers to donate a total of $1000 before I make the next
series. This may seem like a high amount, but if only 200 people
donate $5, that is a thousand dollars.
Now, what if you don’t have the money to donate? I will be making a
post on manwithcode.com named Ruby Video Tutorial Feedback, if 1000
people leave feedback (i.e. What they liked, what they didn’t like).
So whatever comes first, 1000 comments or $1000 will cause me to start
the next video series.
For updates on how close we are to each goal, I will be on twitter at
the account tylerjchurch and with the tag #manwithcode.