Join Jess Chadwick for an in-depth discussion in this video Defining a class, part of TypeScript Essential Training.
At its core, the ES6 class syntax is actually pretty simple. To demonstrate, I'll convert the prototype-based example from the previous video, shown here in the comments, to use the class syntax instead. I'll start by defining the class itself, which is just the class keyword followed by the class name, in this case, TodoService, followed by brackets that contain the class's members. Then I can begin adding members to the class. The syntax you use to define members of a class is almost exactly the same syntax as the one you used to define members of an interface.
When I try to assign a property on the this object in the class's constructor, TypeScript yells at me saying, "Hey, you're try to assign a value to a property "that I don't know about!" That's a good thing. TypeScript is trying to make me define a property before I access it. Okay, but how do I do that? Well there's a couple of ways. The first and simplest way is to define the property, just like I did on the interface, by defining the member outside of the constructor like this. Now up to this point, everything I've shown you is just ECMAScript 6 class syntax, but here's where TypeScript comes into play.
By allowing me to specify type information on this property, this syntax tells TypeScript that the TodoService has a property named todos that can contain an array of todo objects, but it doesn't actually create the property. That only happens in the constructor when I call this.todos equals new array on line 18. However, I can combine these two operations by defining a property and initializing it with a value all in one expression like this.
This approach is a great way to define an initial variable that's the same every single time a new object is created. But in a lot of cases, you may find that you would like to accept these initial values as parameters to the constructor function, as opposed to the hard coded values I've shown here. In other words, you'll end up doing this. Since this is a pretty standard practice, TypeScript actually gives you one more bit of syntactic sugar, and that is the ability to define a constructor parameter and a class property all in one expression, simply by putting an access modifier, such as private, in front of it.
In this example, that means that all five of these lines can be condensed into one single expression. Finally, now that I've defined and assigned the todos property, I can update the code in the getAll method to retrieve my todos by referencing them as this.todos just like in the prototype-based approach. With that in place, let's take a look at the code that TypeScript generates. Does that look familiar? That's right, after all of this syntactic sugar is stripped away and compiled down, TypeScript is just creating a prototype-based object underneath it all from likes 12 to 20.
That's why the bulk of the code that you'll write inside of your methods will still look pretty much exactly the same as it did when you were using the prototype-based syntax, because it is still prototype-based. Regardless of that fact, I found the class syntax to be a highly effective way to both think about and implement object-based behavior. And this syntax becomes even more powerful as you implement the rest of the features in this chapter to build out nice, clean, maintainable objects. So move on to the next videos, where I'll show you all of the ways that you can extend and leverage TypeScript classes.
- What is TypeScript?
- Installing TypeScript
- Creating a TypeScript project
- Reviewing ES6 language features
- Defining custom and anonymous types
- Defining and implementing TypeScript classes
- Working with generics
- Organizing code with namespaces
- Switching modules
- Importing modules
- Debugging TypeScript
- Implementing decorators