Youp Bernoulli
Youp Bernoulli

Reputation: 5635

Typescript type for (Angular) custom web element

Having an Angular component with a corresponding element host which is passed through to a method in TypeScript like this:

constructor(hostElementRef: ElementRef, ipeConfigurationService: IPEConfigurationService) {
  this.ipeConfigurationService = ipeConfigurationService;
  this.ipeConfigurationService.registerHostElement(hostElementRef.nativeElement);
}

public registerHostElement(value: HTMLElement) {
  this._hostElement = value;
}

public toggleFullScreen(): void {
    if (!this._isFullScreen && this._hostElement) {
        if (this._hostElement.requestFullscreen) {
            this._hostElement.requestFullscreen();
        } else if (this._hostElement.mozRequestFullScreen) {
            this._hostElement.mozRequestFullScreen();
        } else if (this._hostElement.webkitRequestFullscreen) {
            this._hostElement.webkitRequestFullscreen();
        } else if (this._hostElement.msRequestFullscreen) {
            this._hostElement.msRequestFullscreen();
        }
    } else if (this._isFullScreen && this._hostElement) {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        }
    }
}

Gives an error when running: "mozRequestFullScreen does not exist on type HTMLElement".

If I change the hostElement to be: any there is no problem. I would like to declare the type usage as explicitly as possible preventing the use of any as much as possible. Any light or advice on this?

Upvotes: 0

Views: 361

Answers (2)

Estus Flask
Estus Flask

Reputation: 222309

HTMLElement interface just doesn't have this property.

If built-in type doesn't provide expected properties, an interface can be merged or extended, or union type can be specified.

Since merged interface will impose global behaviour, it's undesirable for resolving local typing issues.

Union type:

public toggleFullScreen(): void {
  interface RequestFullscreen {
    mozRequestFullscreen(): void;
  }
  ...
  const hostElement = <HTMLElement & RequestFullscreen>this._hostElement;
  hostElement.mozRequestFullscreen
  ...
}

Extended interface:

public toggleFullScreen(): void {
  interface RequestFullscreenElement extends HTMLElement {
    mozRequestFullscreen(): void;
  }
  ...
  const hostElement = <RequestFullscreenElement>this._hostElement;
  hostElement.mozRequestFullscreen
  ...
}

Merged local interface (although it looks misleading and cannot be recommended):

public toggleFullScreen(): void {
  interface HTMLElement {
    mozRequestFullscreen(): void;
  }
  ...
  const hostElement = <HTMLElement>this._hostElement;
  hostElement.mozRequestFullscreen
  ...
}

Upvotes: 1

nicowernli
nicowernli

Reputation: 3348

Your are getting that error because HTMLElement has no mozRequestFullScreen property or method. Check that here.

You might find some light to your problem in this other post

Upvotes: 0

Related Questions