TetraDev TetraDev - 4 months ago 77
Javascript Question

Typescript: Overriding / extending Lib.d.ts with preexisting identifer

I need to get typescript to stop complaining about my code. It runs fine in the browser but fullscreen api are not official yet so typescript definitions aren't up to date.

I am calling document.documentElement.msRequestFullscreen. This causes type error:

Property 'msRequestFullscreen' does not exist on type 'HTMLElement'.


Upon looking at lib.d.ts, I find this:

documentElement: HTMLElement;


So documentElement is set to type HTMLElement. I tried adding a custom definition to override documentElement. My Custom definition:

// Extend Document Typings
interface Document {
msExitFullscreen: any;
mozCancelFullScreen: any;
documentElement: {
msRequestFullscreen: any;
mozRequestFullScreen: any;
}
}


I tried extending the interface for Document but it gives error

Error is:

lib.d.ts:5704:5
Duplicate identifier 'documentElement'.


My typescript class

export class ToggleFullScreen {
viewFullScreenTriggerID: string;
viewFullScreenClass: string;
cancelFullScreenClass: string;
viewFullscreenElem: any;
activeIcon: string;
notFullscreenIcon: string;
isFullscreenIcon: string


constructor() {
this.viewFullScreenTriggerID = "#fullScreenTrigger";
this.viewFullScreenClass = "not-fullscreen";
this.cancelFullScreenClass = "is-fullscreen";
this.notFullscreenIcon = "/assets/icon/fullscreen-enter.svg";
this.isFullscreenIcon = "/assets/icon/fullscreen-exit.svg";
this.activeIcon = this.notFullscreenIcon;
}

toggleFullScreen() {
this.viewFullscreenElem = document.querySelector(this.viewFullScreenTriggerID);

if (this.viewFullscreenElem.classList.contains(this.viewFullScreenClass)) {

var docElm = document.documentElement;
if (docElm.requestFullscreen) {
docElm.requestFullscreen();
} else if (docElm.msRequestFullscreen) {
docElm.msRequestFullscreen();
} else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
} else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
}

this.viewFullscreenElem.classList.toggle(this.viewFullScreenClass);
this.viewFullscreenElem.classList.toggle(this.cancelFullScreenClass);
this.activeIcon = this.isFullscreenIcon;

}

else if (this.viewFullscreenElem.classList.contains(this.cancelFullScreenClass)) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}

this.viewFullscreenElem.classList.toggle(this.viewFullScreenClass);
this.viewFullscreenElem.classList.toggle(this.cancelFullScreenClass);
this.activeIcon = this.notFullscreenIcon;
}
}
}


What is the proper way to get typescript compile errors to stop?

UPDATE: I found a workaround. Instead of trying to override documentElement, which is set to type HTMLElement, I extended HTMLElement and added the properties which were missing.

// Extend Document Typings
interface Document {
msExitFullscreen: any;
mozCancelFullScreen: any;
}


interface HTMLElement {
msRequestFullscreen: any;
mozRequestFullScreen: any;
}

Answer

You can't override existing properties of an existing interface, only add new ones.

Based on the MDN Using fullscreen mode and Element documentation you need to have:

Element.requestFullscreen()

Which exists in the lib.d.ts and lib.es6.d.ts.

If you're missing msRequestFullscreen and mozRequestFullScreen then you need to add them to Element:

interface Document {
    msExitFullscreen: any;
    mozCancelFullScreen: any;
}

interface Element {
    msRequestFullscreen(): void;
    mozRequestFullScreen(): void;
}

document.documentElement.mozRequestFullScreen(); // no error