繁体   English   中英

我如何让打字稿停止抱怨它不知道的功能?

[英]How do I get typescript to stop complaining about functions it doesn't know about?

我正在将 Typescript 用于需要使用 JavaScript 全屏 API 的 Web 应用程序。 全屏 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'.  

当然打字稿无法知道这些功能的存在,但我也不希望重新申报文件作为any只是为了摆脱这些错误的,因为那时我会失去所有其他类型的提示。

这里的解决方案是什么? 如何让 TypeScript 停止抱怨但尽可能多地保留类型注释?

我也有同样的问题。 只需使用“方括号”符号来解决它。

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

简单地说,您可以将这些项目添加到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);

除了Fenton的回答之外,我们还为这些类型添加了一些细节,并在带有导入/导出的常规 TypeScript 模块中声明了它们。 这意味着您还必须声明全局命名空间:

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>;
  }
}

史蒂夫芬顿的回答非常好,从长远来看,这是你应该做的。 记住类型是文档,将帮助下一个开发人员。

不好但证明打字稿是允许的,如果你想要的话

纯粹作为一个思想实验,您可以创建一个局部变量来隐藏全局变量,并将其明确键入为any一次:

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();
        }
    }
}

不推荐这样做,而是阻止编译器抱怨的另一种解决方案:

const document: any = window.document;

我今天遇到了同样的问题,我在这里看到的解决方案并没有完全适用于我们的 angular 7 项目。

这是我们为使其工作所做的工作。 如上所述,我们首先为 Document 创建了一个接口。 (在我们的例子中,我们只需要 'fullscreenElement',但你可以添加任何你喜欢的元素)。

export interface Document extends HTMLDocument {
    fullscreenElement: any;
}

将其导入到我们的组件中而不实施它。

import { Document } from '../interfaces/document';

然后,您可以将document转换为我们上面创建的扩展类型,而不是使用document.fullscreenElement ,如下所示:

(document as Document).fullscreenElement

这使我们能够制作一个全屏变化检测器,如下所示:

@HostListener('document:fullscreenchange', ['$event']) onfullscreenchange(e) {
  if ((document as Document).fullscreenElement) {
    this.isFullscreen = true;
  } else {
    this.isFullscreen = false;
  }
}

Typescript 现在将接受这些新定义的属性。

您可以在访问属性和函数之前强制转换为“any”。

例子:

if ((<any> canvas).mozRequestFullScreen) {
    (<any> canvas).mozRequestFullScreen();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM