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.
class Person { name: string; constructor(theName: string) { this.name = theName; } introduceSelf() { console.log("Hi, I am " + this.name + "!"); } } let personA = new Person("Sally"); personA.introduceSelf();
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.
class Person { name: string; constructor(theName: string) { this.name = theName; } introduceSelf() { console.log("Hi, I am " + this.name + "!"); } } let personA = new Person("Sally"); // Prints "Hi, I am Sally!" personA.introduceSelf(); personA.name = "Mindy"; // Prints "Hi, I am Mindy!" personA.introduceSelf();
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.
class Person { private name: string; constructor(theName: string) { this.name = theName; } introduceSelf() { console.log("Hi, I am " + this.name + "!"); } } class Friend extends Person { yearsKnown: number; constructor(name: string, yearsKnown: number) { super(name); this.yearsKnown = yearsKnown; } timeKnown() { console.log("We have been friends for " + this.yearsKnown + " years.") } } let friendA = new Friend("Jacob", 6); // Prints: Hi, I am Jacob! friendA.introduceSelf(); // Prints: We have been friends for 6 years. friendA.timeKnown();
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.
class Person { private name: string; protected age: number; protected constructor(theName: string, theAge: number) { this.name = theName; this.age = theAge; } introduceSelf() { console.log("Hi, I am " + this.name + "!"); } } class Friend extends Person { yearsKnown: number; constructor(name: string, age: number, yearsKnown: number) { super(name, age); this.yearsKnown = yearsKnown; } timeKnown() { console.log("We have been friends for " + this.yearsKnown + " years.") } friendSince() { let firstAge = this.age - this.yearsKnown; console.log(`We have been friends since I was ${firstAge} years old.`) } } let friendA = new Friend("William", 19, 8); // Prints: We have been friends since I was 11 years old. friendA.friendSince();
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.
Powered by WPeMatico