Как мне получить typescript, чтобы перестать жаловаться на функции, о которых он не знает?

Я использую Typescript для веб-приложения, которое должно использовать полноэкранный API JavaScript. Полноэкранный API официально не поддерживается, поэтому вы должны использовать префиксы поставщиков. Здесь мой код, основанный на образце 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();
        }
    }
}

Однако в моей среде IDE (Visual Studio, но это произойдет где угодно), я получаю такие ошибки, как:

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'.  

Конечно, Typescript не может знать, что эти функции существуют, но я также не хочу повторно объявлять документ как any, чтобы избавиться от этих ошибок, потому что тогда я потеряю все подсказки другого типа.

Какое здесь решение? Как мне получить Typescript, чтобы перестать жаловаться, но сохранить как можно больше аннотаций типа?

Ответ 1

Упрощенно, вы можете добавить эти элементы в интерфейс Document, и ошибки исчезнут.

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

Вы можете добавить полную информацию о типе для каждого из них, даже простое:

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

Это предотвратит их неправильное использование.

Для статических свойств вам просто нужно сделать тип динамическим, важная часть в приведенном ниже примере - это утверждение типа на Element, то есть (<any>Element):

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

Ответ 2

Стив Фентон отвечает отлично, и в конечном итоге это то, что вы должны делать. Помните, что типы являются документацией и помогут следующему разработчику.

Плохо, но убедитесь, что typescript разрешительный, если вы хотите, чтобы он был

Чисто как мысленный эксперимент вы можете создать локальную переменную, чтобы затенять глобальную и явно ввести ее только один раз:

function toggleFullScreen(element: JQuery) {
    var document:any = window.document;
    document.AnythingCanHappen = 123; // No error 
}

И для более причудливых (захватить из внешнего пространства):

var Element_Copy=Element; 
function toggleFullScreen(element: JQuery) {
    var Element:any = Element_Copy; 
    Element.ShootMyself = true;
} 

Полный пример:

var Element_Copy=Element;                         // Magic
function toggleFullScreen(element: JQuery) {
    var document:any = window.document;           // Magic
    var Element:any = Element_Copy;               // Magic
    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();
        }
    }
}

Ответ 3

У меня та же проблема. Просто используйте обозначение "Квадратная скобка", чтобы решить эту проблему.

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

Ответ 4

Это не рекомендуется, но другое решение, чтобы остановить жалобу компилятора:

const document: any = window.document;