Have a Question?

We have come a long way in learning TypeScript since starting this series. The first tutorial gave you a brief introduction of TypeScript and suggested some IDEs that you can use for writing TypeScript. The second tutorial focused on data types, and the third tutorial discussed the basics of interfaces in TypeScript.

As you might already know, JavaScript has only recently added native support for classes and object-oriented programming. However, TypeScript has allowed developers to use classes in their code for a long time. This code is then compiled to JavaScript that will work across all major browsers. In this tutorial, you will learn about classes in TypeScript. They are similar to their ES6 counterparts but are stricter.

Creating Your First Class

Let’s start with the basics. Classes are a fundamental part of object-oriented programming. You use classes to represent any entity which has some properties and functions that may act on given properties. TypeScript gives you full control over the properties and functions that are accessible inside and outside their own containing class. Here is a very basic example of creating a Person class.

The above code creates a very simple class called Person. This class has a property called name and a function called introduceSelf. The class also has a constructor, which is also basically a function. However, constructors are special because they are called every time we create a new instance of our class.

You can also pass parameters to constructors in order to initialize different properties. In our case, we are using the constructor to initialize the name of the person that we are creating using the Person class. The introduceSelf function is a method of the Person class, and we are using it here to print the name of the person to the console. All these properties, methods, and the constructor of a class are collectively called class members.

You should keep in mind that the Person class does not automatically create a person by itself. It acts more like a blueprint with all the information about the attributes a person should have once created. With that in mind, we created a new person and named her Sally. Calling the method introduceSelf on this person will print the line “Hi, I am Sally!” to the console.

Private and Public Modifiers

In the previous section, we created a person named Sally. Right now, it is possible to change the name of the person from Sally to Mindy anywhere in our code, as shown in the following example.

You might have noticed that we were able to use both the name property and the introduceSelf method outside the containing class. This is because all the members of a class in TypeScript are public by default. You can also explicitly specify that a property or method is public by adding the keyword public before it.

Sometimes, you don’t want a property or method to be accessible outside its containing class. This can be achieved by making those members private using the private keyword. In the above code, we could make the name property private and prevent it from being changed outside the containing class. After this change, TypeScript will show you an error saying that the name property is private and you can only access it inside the Person class. The screenshot below shows the error in Visual Studio Code.

Inheritance in TypeScript

Inheritance allows you to create more complex classes starting from a base class. For example, we can use the Person class from the previous section as a base to create a Friend class that will have all the members of the Person and add some members of its own. Similarly, you could also add a Family or Teacher class.

They will all inherit the methods and properties of the Person while adding some methods and properties of their own to set them apart. The following example should make it clearer. I have also added the code for the Person class here so that you can easily compare the code of both the base class and the derived class.

As you can see, you have to use the extend keyword for the Friend class to inherit all the members of the Person class. It is important to remember that the constructor of a derived class must always invoke the constructor of the base class with a call to super().

You might have noticed that the constructor of Friend did not need to have the same number of parameters as the base class. However, the first name parameter was passed to super() in order to invoke the constructor of the parent, which also accepted one parameter. We did not have to redefine the introduceSelf function inside the Friend class because it was inherited from the Person class.

Using the Protected Modifier

Up to this point, we have only made the members of a class either private or public. While making them public allows us to access them from anywhere, making the members private limits them to their own containing class. Sometimes you might want the members of a base class to be accessible inside all the derived classes.

You can use the protected modifier in such cases to limit the access of a member only to derived classes. You can also use the protected keyword with the constructor of a base class. This will prevent anyone from creating an instance of that class. However, you will still be able to extend classes based on this base class.

In the above code, you can see that we made the age property protected. This prevents the use of age outside any classes derived from Person. We have also used the protected keyword for the constructor of the Person class. Declaring the constructor as protected means that we will no longer be able to directly instantiate the Person class. The following screenshot shows an error that pops up while trying to instantiate a class with the protected constructor.

Final Thoughts

In this tutorial, I have tried to cover the basics of classes in TypeScript. We began the tutorial by creating a very basic Person class that printed the name of the person to the console. After that, you learned about the private keyword, which can be used to prevent the members of a class from being accessed at any arbitrary point in the program.

Finally, you learned how to extend different classes in your code using a base class with inheritance. There is a lot more that you can learn about classes in the official documentation.

If you have any questions related to this tutorial, let me know in the comments.