Typescript constructor interfaces

Viewed 33

I've taken this example from docs

interface ClockConstructor {
  new (hour: number, minute: number): ClockInterface;
}

interface ClockInterface {
  tick(): void;
}

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);

As the doc says:

Because createClock’s first parameter is of type ClockConstructor, in createClock(AnalogClock, 7, 32), it checks that AnalogClock has the correct constructor signature.

I wonder that no restriction is applied on not having a constructor, so if I change the AnalogClock class like below, Typescript would not give me any errors.

class AnalogClock implements ClockInterface {
    // constructor(h: number, m: number) {}  <-- this like commented out.
    tick() {
      console.log("tick tock");
    }
  }
1 Answers

If you don't specify constructor explicitly, default constructor will be used instead according to MDN Docs

class AnalogClock implements ClockInterface {
  tick() {
    console.log("tick tock");
  }
}

// is equal to
class AnalogClock implements ClockInterface {
  constructor() {}

  tick() {
    console.log("tick tock");
  }
}

As well constructor will inherit super(...args) call if you do not specify constructor on child class

class Ancestor {
  foo: string;
  
  constructor(foo: string) {
    this.foo = foo;
  }
}

class Child extends Ancestor {
  constructor(foo: string) {
    super(foo);
  }
}

// equals to
class Child extends Ancestor {}

playground link

Related