Ben
Ben

Reputation: 3674

What does the new keyword mean in a interface

If I have the following interfaces:

interface CustomElementConstructor {
    new (...params: any[]): HTMLElement;
}

interface CustomElementRegistry {
    define(name: string, constructor: CustomElementConstructor): void;
}

interface Window {
    customElements: CustomElementRegistry
}

What types is the constructor parameter constrained to? See from the interface definition I would expected it to be a object which has a constructor which returns a type of HTMLElement. But for the following, TypeScript throws a error (and the source is indeed invalid):

class X {
  constructor(): HTMLElement {
    return document.createElement("div") as HTMLElement;
  }
}

customElements.define("hi", X);

Is this because TypeScript does not declaring a different return type other than itself for a constructor? Or is there something more complex around the new value in a interface...?

Upvotes: 1

Views: 152

Answers (1)

D. Pardal
D. Pardal

Reputation: 6597

The first error you get is TS 1093: Type annotation cannot appear on a constructor declaration.. This is because in a class definition, the constructor always returns an instance of a class, in this case, an instance of X.

And that also explains the next error, which is TS 2345: Argument of type 'typeof X' is not assignable to parameter of type 'CustomElementConstructor'.. The constructor returns an instance of X, and an instance of X (A.K.A. an object of type X) has no properties from HTMLElement.

I think you want to define the class X as a subclass of HTMLDivElement, so each instance of X is also a valid instance of HTMLElement, like this:

class X extends HTMLDivElement {
  constructor() {
    super();
  }
}

customElements.define("hi", X);

Upvotes: 1

Related Questions