Typescript is free, open source and OOPs based programming language and created and maintained by Microsoft. Basically, it is a superset of Javascript and helps us to write good quality of code without much complexity and more helps to those developers who have working experience on OOPs based programming language like C#, Java etc. and they want to work in the same manner in client side technology as well. It provides the functionality of Object Oriented Programming like class, Interface, Inheritance, Encapsulation etc. Typescript basically gives you a way to write the Javascript. The Typescript program compiles and creates the plain Javascript code.

We generally use the TypeScript for the following reasons.

  • Provides the OOPs functionality.
  • Easy to manage the code.
  • Compile the code and convert into plain Javascript, so run to any browser.
  • Maintained and supported by Microsoft.
  • Works with most of the library like JQuery, Backbone, Underscore etc.
  • Supported by most of the framework like Angular, Node etc.
  • Code complexity is less as compare to javascript code.

Today, we will learn about Inheritance in typescript which is one of the pillars of Object Oriented Programming. We will see different examples of how to implement inheritance in TypeScript. Before getting started let me tell you how you will install the typescript using NPM and compile and run your typescript file (.ts extension).

For installing the typescript, you should run the following command.

npm install typescript -g

For compiling and running the typescript code using a file, you can use commands as follows.

npm filename.ts // Compile the typescript file and create javascript file.

node filename.js // Run the created javascript file.

 

Before moving next and try to demonstrate the Inheritance in TypeScript, I hope, you will have some idea about OOPs (Object Oriented Programming), if not, not an issue. We will learn most of the things here.

Inheritance is a concept in which a class inherit some other class features and reuse it. In other words, we can say, it is a mechanism where a class which is called child class or subclass acquire the functionality (Properties and Behaviors) of the other class which is called parent class or base class. So, rather than writing the same functionality again and again, we just try to reuse from some existing class which has already implemented this functionality.

We have multiple types of inheritance:

  • Single Inheritance: Here one class is extended by only one class.
  • Multi-level Inheritance: Here one class is extended by other class and other class is also extended by some other class and it can be multi-level.
  • Multiple Inheritance: It is not supported by typescript using classes but can be achieved using Interfaces.

 

Let say for an example to understand inheritance, we have a class Vehicles which has some common properties like the color of the vehicles, name of vehicles etc. and some of the behaviors like start, stop etc. We are writing some other class like Cars then we will write the same code for a car as well, it is because the car is a type of Vehicles. So, rather than writing the same code again and again, we can use the existing class(Vehicles) functionality in Cars class. If some other functionality is required which are not present in Vehicles class than we can write it from scratch in Car class. We hope you are clear with what is inheritance in typescript is and how it works.

So, let move to practical demonstration and try to understand the Inheritance in Typescript. First of all, let me show you the basic syntax of Inheritance in typescript.

class BaseClass{
    // Some other code goes here
}

class ChildClass extends BaseClass{
    // Some other code goes here
}

As per the above code, you can see, here we have one BaseClass and a ChildClass which extending the features of the BaseClass. So, let move to the next example and understand it in a more descriptive way. 

 

Example: 1

As the code shown in example 1, we have two classes like Vehicles and Cars with the basic constructor. In typescript, if you are extending any class then first, you have to call the super(). Basically, it must call super() before calling anything else or using "this" in child class constructor body. You can take it as a rule of typescript, which must be followed. To run the Cars class, first, we have to create an instance of the cars class. As you create the instance of the cars class, constructors will call automatically.

class Vehicles{
    constructor(){
        console.log('I am base class.')
    }
}

class Cars extends Vehicles{
    constructor(){
        super();
        console.log('I am child class.')
    }
}

let car = new Cars();

Once you compile the code using commands as we have already discussed above. The generated javascript code will be like as follows. As you can see and compare the code complexity between both codes. Typescript code is much easier to understand as compared to javascript.

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Vehicles = /** @class */ (function () {
    function Vehicles() {
        console.log('I am base class.');
    }
    return Vehicles;
}());
var Cars = /** @class */ (function (_super) {
    __extends(Cars, _super);
    function Cars() {
        var _this = _super.call(this) || this;
        console.log('I am child class.');
        return _this;
    }
    return Cars;
}(Vehicles));
var car = new Cars();

If you run the above typescript code using "node filename.js" command than output will be as follows. 

I am base class.
I am child class.

 

Example: 2

Let's extends the above example 1 and create the parameterized constructor. You can see with the following example, Vehicles class has three properties like color, name and type. On the other hand, Cars class is extending the Vehicles class (Base class). Cars class has one extra property as a price of the car which number data types. When you create the constructor of child class (Cars) and you have some extra properties apart from base class(Vehicles) properties than you have to provide all in child class(Cars) constructor as parameters. 

Note: Call the super() just before calling anything else.

class Vehicles {

    color: string;
    name: string;
    type: string;

    constructor(_color: string, _name: string, _type: string) {
        console.log('I am base class.')

        this.color = _color;
        this.name = _name;
        this.type = _type;

    }
}

class Cars extends Vehicles {

    price: number;

    constructor(_color: string, _name: string, _type: string, _price: number) {
        super(_color, _name, _type);
        console.log('I am child class.')

        this.price = _price;

        console.log('This is ' + this.color + ' ' + this.type + ' with price ' + this.price);
    }
}

let car = new Cars('Black', 'Honda', 'Car', 200000);

Here is the compiled javascript code for above typescript code. 

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Vehicles = /** @class */ (function () {
    function Vehicles(_color, _name, _type) {
        console.log('I am base class.');
        this.color = _color;
        this.name = _name;
        this.type = _type;
    }
    return Vehicles;
}());
var Cars = /** @class */ (function (_super) {
    __extends(Cars, _super);
    function Cars(_color, _name, _type, _price) {
        var _this = _super.call(this, _color, _name, _type) || this;
        console.log('I am child class.');
        _this.price = _price;
        console.log('This is ' + _this.color + ' ' + _this.type + ' with price ' + _this.price);
        return _this;
    }
    return Cars;
}(Vehicles));
var car = new Cars('Black', 'Honda', 'Car', 200000);

 

Example: 3

Here, we have one more example similar to example 2 but this time, we don't have any extra property in the child class (Cars). We have only one getter property which is returning the name of the base class (Vehicles). Here you can see, we don't require to create the constructor in the child class (Cars) because child class does not have any extra property. 

class Vehicles {

    color: string;
    name: string;
    type: string;

    constructor(_color: string, _name: string, _type: string) {
        console.log('I am base class.')

        this.color = _color;
        this.name = _name;
        this.type = _type;

    }
}

class Cars extends Vehicles {
  
    get Name(){
        return this.name;
    }
    
}

let car = new Cars('Red', 'Suzuki', 'Car');
console.log('Car Name is '+car.Name);

Here is the compile javascript code for example 3. 

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Vehicles = /** @class */ (function () {
    function Vehicles(_color, _name, _type) {
        console.log('I am base class.');
        this.color = _color;
        this.name = _name;
        this.type = _type;
    }
    return Vehicles;
}());
var Cars = /** @class */ (function (_super) {
    __extends(Cars, _super);
    function Cars() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Object.defineProperty(Cars.prototype, "Name", {
        get: function () {
            return this.name;
        },
        enumerable: true,
        configurable: true
    });
    return Cars;
}(Vehicles));
var car = new Cars('Red', 'Suzuki', 'Car');
console.log('Car Name is ' + car.Name);

 

Example: 4

Here is the example 4 for inheritance in typescript practical demonstration. Let me clear, how we can create the method (function) in the child class (Cars) and access it using an instance of the child class. It is, as usual, we access the method of any class using the instance of the class.

class Vehicles {

    color: string;
    name: string;    

    constructor(_color: string, _name: string) {
        this.color = _color;
        this.name = _name;
    }
}

class Cars extends Vehicles {
  
    maxSpeed: number;

    constructor(_color: string, _name: string, _maxSpeed: number) {
        super(_color, _name);
        this.maxSpeed =_maxSpeed;
    }

    getSpeed(){
        console.log('The max speed of '+this.name+ ' is '+this.maxSpeed);
    }
}

let car = new Cars('Red', 'Suzuki', 120);
car.getSpeed();

 

Example: 5

Here, we are providing the code in which you will see, how a child class (Cars) can override the behavior of the base class. As you can see in the following example, we have one method as "getSpeed()" and similar name method is also available in the child class (Cars). This type of situation is called overriding in OOPs. Here we are overriding the base class functionality in the child class.

class Vehicles {

    color: string;
    name: string;
    speed: number;

    constructor(_color: string, _name: string, _speed: number) {
        this.color = _color;
        this.name = _name;
        this.speed = _speed;
    }

    getSpeed() {        
        console.log('The average speed of ' + this.name + ' is ' + this.speed);
    }
}

class Cars extends Vehicles {

    maxSpeed: number;

    constructor(_color: string, _name: string, _speed: number, _maxSpeed: number) {
        super(_color, _name, _speed);
        this.maxSpeed = _maxSpeed;
    }

    getSpeed() {
        super.getSpeed();
        console.log('The max speed of ' + this.name + ' is ' + this.maxSpeed);
    }
}

let car = new Cars('Red', 'Suzuki', 100, 120);
car.getSpeed();

 

Example: 6

This is our last example and best example. Here we are trying to achieve multiple inheritances in typescript. As you know, multiple inheritances are not supported in many languages. But we can achieve it using the interfaces. In multiple inheritances, we try to extend the functionality of two classes at the same time. But in typescript, we can extend more than one typescript class at a time. So, if you would like to extend multiple features at a time when you can create interfaces. A class in typescript can implement multiple interfaces at a time.

As per the below example, we have two interfaces like IFeature1 and IFeature2. There is one Feature class which is implementing both interfaces features at a time.

interface IFeature1{
    getFeature1();
}

interface IFeature2{
    getFeature2();
}

class Feature implements IFeature1, IFeature2{

    getFeature1(){
        console.log('This is feature one.')
    }

    getFeature2(){
        console.log('This is feature two.')
    }
}

class Car extends Feature{

    getCarFeature(){

        super.getFeature1();
        super.getFeature2();
    }
}

let car = new Car();
car.getCarFeature();

Here is the compile javascript code for above typescript example 6.

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Feature = /** @class */ (function () {
    function Feature() {
    }
    Feature.prototype.getFeature1 = function () {
        console.log('This is feature one.');
    };
    Feature.prototype.getFeature2 = function () {
        console.log('This is feature two.');
    };
    return Feature;
}());
var Car = /** @class */ (function (_super) {
    __extends(Car, _super);
    function Car() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Car.prototype.getCarFeature = function () {
        _super.prototype.getFeature1.call(this);
        _super.prototype.getFeature2.call(this);
    };
    return Car;
}(Feature));
var car = new Car();
car.getCarFeature();

 

Conclusion

So, today we have learned about Inheritance in Typescript and different examples for Inheritance implementation using Typescript.

I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends. Thanks

You are here, it means, you have read something useful. So, If you like this article then please connect me on @Facebook@Twitter@LinkedIn@Google+.