Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class constructor type in typescript?

How can I declare a class type, so that I ensure the object is a constructor of a general class?

In the following example, I want to know which type should I give to AnimalClass so that it could either be Penguin or Lion:

class Animal {     constructor() {         console.log("Animal");     } }  class Penguin extends Animal {     constructor() {         super();         console.log("Penguin");     } }  class Lion extends Animal {     constructor() {         super();         console.log("Lion");     } }  class Zoo {     AnimalClass: class // AnimalClass could be 'Lion' or 'Penguin'      constructor(AnimalClass: class) {         this.AnimalClass = AnimalClass         let Hector = new AnimalClass();     } } 

Of course, the class type does not work, and it would be too general anyway.

like image 752
arthur.sw Avatar asked Sep 21 '16 10:09

arthur.sw


People also ask

What is class constructor in TypeScript?

A constructor is a special function of the class that is responsible for initializing the variables of the class. TypeScript defines a constructor using the constructor keyword. A constructor is a function and hence can be parameterized. The this keyword refers to the current instance of the class.

What is the return type of constructor in TypeScript?

typeof Animal is a TypeScript type annotation which "returns" the type of the Animal constructor function.

Do TypeScript classes need a constructor?

Classes in TypeScript do not require you to explicitly write a constructor. However if you are extending a base class you will need to create a constructor to call super() at a minimum.

How do you call a constructor in TypeScript?

In TypeScript, the constructor method is always defined with the name "constructor". In the above example, the Employee class includes a constructor with the parameters empcode and name . In the constructor, members of the class can be accessed using this keyword e.g. this. empCode or this.name .


2 Answers

Edit: This question was answered in 2016 and is kind of outdated. Look at @Nenad up-to-date answer below.

Solution from typescript interfaces reference:

interface ClockConstructor {     new (hour: number, minute: number): ClockInterface; } interface ClockInterface {     tick(); }  function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {     return new ctor(hour, minute); }  class DigitalClock implements ClockInterface {     constructor(h: number, m: number) { }     tick() {         console.log("beep beep");     } } class AnalogClock implements ClockInterface {     constructor(h: number, m: number) { }     tick() {         console.log("tick tock");     } }  let digital = createClock(DigitalClock, 12, 17); let analog = createClock(AnalogClock, 7, 32); 

So the previous example becomes:

interface AnimalConstructor {     new (): Animal; }  class Animal {     constructor() {         console.log("Animal");     } }  class Penguin extends Animal {     constructor() {         super();         console.log("Penguin");     } }  class Lion extends Animal {     constructor() {         super();         console.log("Lion");     } }  class Zoo {     AnimalClass: AnimalConstructor // AnimalClass can be 'Lion' or 'Penguin'          constructor(AnimalClass: AnimalConstructor) {         this.AnimalClass = AnimalClass         let Hector = new AnimalClass();     } } 
like image 171
arthur.sw Avatar answered Oct 21 '22 13:10

arthur.sw


I am not sure if this was possible in TypeScript when the question was originally asked, but my preferred solution is with generics:

class Zoo<T extends Animal> {     constructor(public readonly AnimalClass: new () => T) {     } } 

This way variables penguin and lion infer concrete type Penguin or Lion even in the TypeScript intellisense.

const penguinZoo = new Zoo(Penguin); const penguin = new penguinZoo.AnimalClass(); // `penguin` is of `Penguin` type.  const lionZoo = new Zoo(Lion); const lion = new lionZoo.AnimalClass(); // `lion` is `Lion` type. 
like image 34
Nenad Avatar answered Oct 21 '22 12:10

Nenad