Getting Started with Classes in TypeScript: A Beginner’s Guide

In TypeScript, classes are a way to define a blueprint for creating objects with specific properties and methods. To simplify it more we can say that classes are Template for creating Objects.

classes contains state in terms of variables and it also contains behavior in terms of methods.

Here is an example of a basic class in TypeScript:


  class Animal {
    name: string;
    sound:string;
    constructor(name: string,sound:string) {
      this.name = name;
      this.sound=sound;
    }
    makeSound() {
      console.log(`${this.name} makes a sound as ${this.sound}`);
    }
  }
  

In this example, we’ve created a class called Animal with a property called name, sound and a method called makeSound(). The constructor() method is called when an object of the Animal class is created, and it takes a name and sound parameter that is used to set the name and sound property of the object.

How to create an Instance of class?

To create an instance of the Animal class, we can use the new keyword:


  let myAnimal = new Animal('lion','roar');
  console.log(myAnimal.name); // Output: 'lion'
  myAnimal.makeSound();  // Output: 'lion makes a sound as roar' 

Class Constructors in Typescript

In TypeScript, a class constructor is a special method that is executed when an instance of the class is created. The constructor method is defined using the keyword constructor.

Here I am taking same example as mentioned above trying to explain in more deeply.


  class Animal {
    name: string;
    sound:string;
    constructor(name: string,sound:string) {
      this.name = name;
      this.sound=sound;
    }
    makeSound() {
      console.log(`${this.name} makes a sound as ${this.sound}`);
    }
  }
  let myAnimal = new Animal('lion','roar');
  console.log(myAnimal.name); // Output: 'lion'
  myAnimal.makeSound();  // Output: 'lion makes a sound as roar' 

In this example, the Animal class has a constructor that takes in two arguments: name and sound. When a new instance of the Animal class is created using the new keyword, the constructor is automatically called with the provided arguments.

Inside the constructor, the name and sound properties of the instance are set using the this keyword.

The makesound method is defined on the Animal class and can be called on any instance of the class, including myAnimal. When the makeSound method is called on myAnimal, it logs a message to the console using the name and sound properties of the instance.

Optional Parameter in Constructor

In TypeScript, we can make constructor parameters optional by adding a ? symbol after the parameter name. This indicates that the parameter is optional and doesn’t need to be provided when creating an instance of the class.


  class Person {
    name: string;
    age?: number;
  
    constructor(name: string, age?: number) {
      this.name = name;
      this.age = age;
    }
  
    greet() {
      if (this.age) {
        console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
      } else {
        console.log(`Hello, my name is ${this.name}.`);
      }
    }
  }
  
  const john = new Person('John');
  john.greet(); // OutPut: "Hello, my name is John."
  
  const jane = new Person('Jane', 25);
  jane.greet(); // OutPut: "Hello, my name is Jane and I'm 25 years old."

In this example, the Person class has an optional age parameter in its constructor. When creating a new instance of the Person class, the age parameter can be provided or omitted. If the age parameter is provided, it is stored in the age property of the instance. If the age parameter is omitted, the age property will be undefined.

In the greet method, an if statement is used to determine whether the age property is defined. If the age property is defined, a message is logged to the console that includes the name and age properties. If the age property is undefined, a different message is logged that only includes the name property.

Class Expression in Typescript

In TypeScript, a class expression is a way to define a class as a value, just like a function expression defines a function as a value.

A class expression can be used anywhere a value of its type is expected, including as a function argument or as a property of an object.

Here is an example of a class expression in TypeScript:


  const ClassExpression = class {
    private x: number;
    constructor(x: number) {
      this.x = x;
    }
    getX() {
      return this.x;
    }
  }

In this example, ClassExpression is a constant that holds a class expression. The class has a private property x and a constructor that takes a number argument and sets the x property. The class also has a method getX that returns the value of x.

We can create an instance of the class expression just like we would with a regular class:


  const instance = new ClassExpression(42);
  console.log(instance.getX()); // prints 42

Class expressions can also be named:


  const NamedExpressionClass = class MyClass {
    private x: number;
    constructor(x: number) {
      this.x = x;
    }
    getX() {
      return this.x;
    }
  }

In this example, NamedExpressionClass is the variable that holds the class expression, and MyClass is the name of the class that can be used inside the class body. Named class expressions can be useful for debugging or for creating self-referential classes.

Class Inheritance in Typescript

Class inheritance is a powerful feature in object-oriented programming that allows us to define a new class based on an existing class.

In Typescript, class inheritance is supported through the “extends” keyword.

How to Extends class in Typescript?

In Typescript We can also extend a class to create a new class that inherits the properties and methods of the original class. Means to they will contain all methods and properties of their Parent class.


  class Animal {
    name: string;
    sound:string;
    constructor(name: string,sound:string) {
      this.name = name;
      this.sound=sound;
    }
    makeSound() {
      console.log(`${this.name} makes a sound as ${this.sound}`);
    }
  }
  const Cat=class extends Animal {
    constructor(name: string,sound:string) {
      super(name,sound);
    }
    makeSound() {
      console.log(`The cat ${this.sound}`);
    }
    purr() {
      console.log('The cat purrs.');
    }
  }
  
  let myCat = new Cat('Fluffy','meows');
  console.log(myCat.name); // Output: 'Fluffy'
  myCat.makeSound(); // Output: 'The cat meows.'
  myCat.purr(); // Output: 'The cat purrs.'

In this example, we’ve created a Cat class that extends the Animal class. The Cat class has its own makeSound() method that overrides the makeSound() method of the Animal class. It also has a new method called purr(). When we create an instance of the Cat class, it has access to both the makeSound() method from the Animal class and the purr() method from the Cat class.


  abstract class Animal {
    constructor(public name: string) {}
    
    abstract makeSound(): void;
    
    move(distance: number) {
      console.log(`${this.name} moved ${distance} meters.`);
    }
  }
  
  class Dog extends Animal {
    constructor(name: string) {
      super(name);
    }
    
    makeSound() {
      console.log("Woof! Woof!");
    }
  }
  
  const dog = new Dog("Buddy");
  dog.move(10);       // Output: "Buddy moved 10 meters."
  dog.makeSound();    // Output: "Woof! Woof!"

In this example, we have an abstract class called Animal which has a constructor that takes in a name parameter, a method called move that logs how far the animal moved, and an abstract method called makeSound. The makeSound method is declared with the abstract keyword, which means that any subclass of Animal must provide an implementation for this method.

We then create a subclass called Dog which extends Animal and provides an implementation for the makeSound method. We also call the constructor of the parent class using the super keyword.

When we create a new instance of Dog, we pass in the name “Buddy” to the constructor. We can then call both the move and makeSound methods on the dog object.

By using an abstract class, we can define a common interface for a group of related classes (in this case, animals). We can also ensure that any subclass of Animal provides an implementation for the makeSound method.

Abstract Class in Typescript

An abstract class in TypeScript is a class that cannot be directly instantiated but can only be used as a base class for other classes. Abstract classes are defined using the abstract keyword and they provide a way to define a common interface for a group of related classes.

Here’s an example of an abstract class in TypeScript:


  abstract class Animal {
    constructor(public name: string) {}
    
    abstract makeSound(): void;
    
    move(distance: number) {
      console.log(`${this.name} moved ${distance} meters.`);
    }
  }
  
  class Dog extends Animal {
    constructor(name: string) {
      super(name);
    }
    
    makeSound() {
      console.log("Woof! Woof!");
    }
  }
  
  const dog = new Dog("Buddy");
  dog.move(10);       // Output: "Buddy moved 10 meters."
  dog.makeSound();    // Output: "Woof! Woof!"

In this example, we have an abstract class called Animal which has a constructor that takes in a name parameter, a method called move that logs how far the animal moved, and an abstract method called makeSound. The makeSound method is declared with the abstract keyword, which means that any subclass of Animal must provide an implementation for this method.

We then create a subclass called Dog which extends Animal and provides an implementation for the makeSound method. We also call the constructor of the parent class using the super keyword.

When we create a new instance of Dog, we pass in the name “Buddy” to the constructor. We can then call both the move and makeSound methods on the dog object.

By using an abstract class, we can define a common interface for a group of related classes (in this case, animals).

Note: We have to also ensure that any subclass of Animal provides should contain an implementation for the makeSound method because it is an Abstract method.