Class Constructor Type in TypeScript

  1. Typed Constructor in TypeScript
  2. Type for Constructor of a Class in TypeScript

TypeScript has a strongly typed language, and thus every variable and object used in TypeScript has a type, which helps in further debugging and avoiding runtime errors in the application. This tutorial will focus on how to have types for constructors in TypeScript.

Typed Constructor in TypeScript

Normally when we pass objects to a constructor of a class with types. We can have multiple types, even using the union operator.

Code:

interface AcademyInfo {
    name : string;
    country: string;
}

class Academy {
    private id;
    private info;
    private numStudents;
    constructor( info : AcademyInfo, id : string | number,  numStudents? : number){
        this.id = id;
        this.info = info;
        this.numStudents = numStudents ?? 0;
    }

    public getAcademyName(){
        return this.info.name;
    }
}
var academy = new Academy( {name : "Augustine Academy", country: "India"}, "3232dqsx23e", 1000 );

There’s a constructor which supports parameters of varying types such as AcademyInfo, string | number, and number. All these variables can be passed to the constructor of the class when creating instances of the class.

Type for Constructor of a Class in TypeScript

The constructors of class can have types of their own.

Syntax:

type ConstructorType<T> = new (...args : any[]) => T;

Above syntax, generic types are used, indicating that the constructor will return an object that can be a class instance of type T. Using the typed constructor, one can implement the factory design pattern in TypeScript.

Code:

interface Animal {
    speak() : void;
}

interface AnimalConstructor {
    new ( speakTerm : string, name : string, legs: number ) : Animal;
}

const createAnimalFactory = (
    ctor : AnimalConstructor,
    name : string,
    legs : number,
    speakTerm : string
) => {
    return new ctor(speakTerm, name, legs);
};

class Dog implements Animal{
    private name;
    private legs;
    private speakTerm;
    constructor(speakTerm : string, name : string, legs : number){
        this.speakTerm = speakTerm;
        this.legs = legs;
        this.name = name;
    }
    speak(){
        console.log( "Dog " + this.speakTerm + " I have " + this.legs + " legs");
    }
}

class Cat implements Animal{
    private name;
    private legs;
    private speakTerm;
    constructor(speakTerm : string, name : string, legs : number){
        this.speakTerm = speakTerm;
        this.legs = legs;
        this.name = name;
    }
    speak(){
        console.log( "Cat " + this.speakTerm + " I have " + this.legs + " legs");
    }
}
const dog = createAnimalFactory(Dog, "dog", 2, "woof");
const cat = createAnimalFactory(Cat, "cat", 2, "meow");

dog.speak();
cat.speak();

Output:

"Dog woof I have 2 legs"
"Cat meow I have 2 legs"

We have two classes in the above example named Dog and Cat, both implementing the same interface Animal and having different implementations of the speak method.

In the createAnimalFactory method, one can just pass the Dog or the Cat class along with its parameters to create an instance of that particular class.

This design pattern is very useful for making different instances of classes depending on some use case.

Write for us
DelftStack articles are written by software geeks like you. If you also would like to contribute to DelftStack by writing paid articles, you can check the write for us page.

Related Article - TypeScript Constructor

  • Overload Constructors in TypeScript