javascript - Hur får jag typescript att sluta klaga på funktioner det inte känner till?


Jag använder Typescript för en webbapp som behöver använda JavaScripts fullskärms-API. Fullskärms-API:et stöds ännu inte officiellt, så du måste använda leverantörsspecifika prefix. Här är min kod, baserad på exemplet från MDN:

function toggleFullScreen(element: JQuery) {
    var fs = element[0];
    if (!document.fullscreenElement &&    // alternative standard method
        !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {  // current working methods
        if (fs.requestFullscreen) {
            fs.requestFullscreen();
        } else if (fs.msRequestFullscreen) {
            fs.msRequestFullscreen();
        } else if (fs.mozRequestFullScreen) {
            fs.mozRequestFullScreen();
        } else if (fs.webkitRequestFullscreen) {
            fs.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
        }
    } else {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        }
    }
}

Men i min IDE (Visual Studio, men detta skulle hända var som helst), får jag fel som:

The property 'fullscreenElement' does not exist on value of type 'Document'.
The property 'mozFullScreenElement' does not exist on value of type 'Document'.
The property 'webkitFullscreenElement' does not exist on value of type 'Document'.  

Självklart kan TypeScript inte veta att dessa funktioner finns, men jag vill inte heller deklarera om document som any bara för att bli av med dessa fel, eftersom jag då skulle förlora alla andra typanvisningar.

Vad är lösningen här? Hur får jag TypeScript att sluta klaga men behålla så många typanteckningar som möjligt?

Svar #1

Förenklat kan du lägga till dessa objekt i Document-gränssnittet och felen skulle försvinna.

interface Document {
    exitFullscreen: any;
    mozCancelFullScreen: any;
    webkitExitFullscreen: any;
    fullscreenElement: any;
    mozFullScreenElement: any;
    webkitFullscreenElement: any;
}

Du kan lägga till fullständig typinformation för var och en av dessa, även de enkla:

interface Document {
    exitFullscreen: () => void;
    mozCancelFullScreen: () => void;
    webkitExitFullscreen: () => void;
    fullscreenElement: () => void;
    mozFullScreenElement: () => void;
    webkitFullscreenElement: () => void;
}

Detta skulle förhindra att de missbrukas.

För statiska egenskaper kanske du bara behöver göra typen dynamisk, den viktiga delen i exemplet nedan är typnedskrivningen på Element, dvs (<any>Element):

fs.webkitRequestFullscreen((<any>Element).ALLOW_KEYBOARD_INPUT);

Svar #2

Jag har samma problem. Använd bara 'hakparentes'-notationen för att lösa det.

 if (document['exitFullscreen']) {
    document['exitFullscreen']();
 } else if (document['webkitExitFullscreen']) {
    document['webkitExitFullscreen']();
 } else if (document['mozCancelFullScreen']) {
    document['mozCancelFullScreen']();
 } else if (document['msExitFullscreen']) {
    document['msExitFullscreen']();
 }

Svar #3

Som ett tillägg till Fentons svar lade vi till några detaljer till dessa typer och deklarerade dem i en vanlig TypeScript-modul med imports/exports. Detta innebär att du också måste deklarera det globala namnområdet:

declare global {
  interface Document {
    mozCancelFullScreen?: () => Promise<void>;
    msExitFullscreen?: () => Promise<void>;
    webkitExitFullscreen?: () => Promise<void>;
    mozFullScreenElement?: Element;
    msFullscreenElement?: Element;
    webkitFullscreenElement?: Element;
  }

  interface HTMLElement {
    msRequestFullscreen?: () => Promise<void>;
    mozRequestFullscreen?: () => Promise<void>;
    webkitRequestFullscreen?: () => Promise<void>;
  }
}

Relaterade artiklar