Typescript Polymorphism with examples

In this post, learn the basic guide to the Polymorphism concept in typescript.
You can also check Typescript final keyword

What is Polymorphism in Typescript?

It is one of the concepts of Object Oriented Programming_. Other concepts areClasses,Interfaces , Encapsulation🔗 and Abstract classes.

Polymorphism means many forms of a function or method in a class
Typescript supports the polymorphism concept in many ways.

  • function overloading
  • function overriding
  • Interface

typescript Method overriding

Method overriding is allowed the Child class to provide an implementation of a function or method that is already provided by the Superclass of Parent class.

The subclass will have access to all public methods and properties of a Superclass.

Rules:

A function declared in the child class must have the same name as the parent class.

The parameters of a function in parent and child classes are the same.

child classes extend by parent class or follow the inheritance

Typescript method overriding Example

In this, We have declared Parent and Child classes. The parent class is extended from the Child class. These two classes have the same method name processName()

Here processName() is overriding in the child class and providing an implementation.

class Parent {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  processName() {
    console.log("processName method in parent class", name);
  }
}
class Child extends Parent {
  constructor(name: string) {
    super(name);
  }
  processName() {
    console.log("processName method in Child class", name);
  }
}
let myObject = new Child("Kiran");
myObject.processName();
let myObject1 = new Parent("john");
myObject1.processName();

Output:

processName method in the Child class
processName method in the parent class

Method or Function overloading

Function overloading means one method with multiple signatures. Every programming language provides the same. But typescript supports differently.

For example, In Typescript, We can write multiple methods with the different argument like below

class MyClass {
  constructor() {}
  mymethod() {
    console.log("method with No argument");
  }
  mymethod(name: string) {
    console.log("method with string argument");
  }
}
let myclass = new MyClass();
console.log(myclass.mymethod());

It does not Compile and gives an error Duplicate function implementation.

The reason is, Type code is converted to javascript and It has no overloading syntax support.

Then How does typescript supports functional overload?.

yes, It supports function overload in a different way using Any Data type or Optional Parameter Syntax.

You can check my other blog post on Function overload in typescript

Typescript Polymorphism Interfaces or Duck Typing

For Example, We have Interface - DatabaseConnection which has an only abstract method - connect() used to connect the database and return >0 if successful, else return zero or -1 for failed cases.

interface DatabaseConnection {
  connect(): number;
}

We will provide an implementation for the DatabaseConnection interface. Let us say, provide an implementation for MySQL database. MySQLConnection has connect() method implementation for MySQL Database

export class MySQLConnection implements DatabaseConnection {
  public connect(): number {
    console.log("Open HTTP Connection");
    console.log("Connection Established");
    return 1;
  }
}

Also, provide the Database connection mechanism for MongoDB. MongoDBConnection has connect() method implementation for MongoDB Database

export class MongoDBConnection implements DatabaseConnection {
  public connect(): number {
    console.log("Open HTTP Connection");
    console.log("Connection Established");
    return 1;
  }
}

The next step is to write a Client code that connects to Database.

DatabaseTest class is created and provided a constructor by injecting DatabaseConnection.

This is an example of Constructor Injection using interfaces. So you are passing the interface here, Not implementation.

The client need not required a connection to MySQL or MongoDB or something else.

The advantages of the passing interface are flexibility and loose coupling between components and ease in doing unit testing of components. Implementation of Db is decided at Runtime here. It is called a polymorphism interface.

It adds more flexibility, and enables clients to configure.

export class DatabaseTest {
  constructor(private dbConnection: DatabaseConnection) {
    dbConnection.connect();
  }
}

if we inject the implementation class MongoDBConnection into a constructor. we have a tightly coupled system that cannot be extended for future implementations.