抑制 Typescript 警告

10

我有以下typescript代码:

 private addBrowserNameAsCssClassToHtmlTag(): void {
  var rootElement = angular.element(document.querySelector("html"));
  if (this.isOpera()) {
    rootElement.addClass("opera-browser");
  } else if (this.isFirefox()) {
    rootElement.addClass("firefox-browser");
  } else if (this.isSafari()) {
    rootElement.addClass("safari-browser");
  } else if (this.isIE()) {
    rootElement.addClass("ie-browser");
  } else if (this.isChrome()) {
    rootElement.addClass("chrome-browser");
  }
}

private isOpera(): boolean {
  return (!!(<any>window).opr && !!(<any>opr).addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
}

private isFirefox(): boolean {
  //noinspection TypeScriptUnresolvedVariable
  return typeof InstallTrigger !== 'undefined';
}

private isSafari(): boolean {
  return /constructor/i.test(window.HTMLElement) || ((p): boolean => {
      return p.toString() === "[object SafariRemoteNotification]";
    })(!window['safari'] || safari.pushNotification);
}

private isIE(): boolean {
  return /*@cc_on!@*/false || !!window.document.documentMode;
}

private isChrome(): boolean {
  return !!window.chrome && !!window.chrome.webstore;
}

代码可以正常运行,但问题在于它会生成编译时错误:

error TS2304: Cannot find name 'opr'.
error TS2339: Property 'opera' does not exist on type 'Window'.
error TS2304: Cannot find name 'InstallTrigger'.
error TS2339: Property 'HTMLElement' does not exist on type 'Window'.
error TS2304: Cannot find name 'safari'.
error TS2339: Property 'documentMode' does not exist on type 'Document'.
error TS2339: Property 'chrome' does not exist on type 'Window'.
error TS2339: Property 'chrome' does not exist on type 'Window'.

如果我使用普通的JavaScript编写代码,就不会遇到任何问题。如何消除编译器对这部分代码的警告?或者可能有更好的解决方案,我不知道吗?

3个回答

14
一个解决方案:
declare const InstallTrigger: any;

class Abc {
    private addBrowserNameAsCssClassToHtmlTag(): void {
        var rootElement = angular.element(document.querySelector("html"));
        if (this.isOpera()) {
            rootElement.addClass("opera-browser");
        } else if (this.isFirefox()) {
            rootElement.addClass("firefox-browser");
        } else if (this.isSafari()) {
            rootElement.addClass("safari-browser");
        } else if (this.isIE()) {
            rootElement.addClass("ie-browser");
        } else if (this.isChrome()) {
            rootElement.addClass("chrome-browser");
        }
    }

    private isOpera(): boolean {
        return (!!window['opr'] && !!window['opr'].addons) || !!window['opera'] || navigator.userAgent.indexOf(' OPR/') >= 0;
    }

    private isFirefox(): boolean {
        //noinspection TypeScriptUnresolvedVariable
        return typeof InstallTrigger !== 'undefined';
    }

    private isSafari(): boolean {
        return /constructor/i.test(window['HTMLElement']) || ((p): boolean => {
            return p.toString() === "[object SafariRemoteNotification]";
        })(!window['safari'] || window['safari'].pushNotification);
    }

    private isIE(): boolean {
        return /*@cc_on!@*/false || !!window.document['documentMode'];
    }

    private isChrome(): boolean {
        return !!window['chrome'] && !!window['chrome'].webstore;
    }
}

4

简单粗暴的回答,使用方括号表示法,在TS中它们不进行类型检查。

window["opera"]

另一个选项是扩展全局接口,当您构建TypeScript时,编译器会包含一个“基本” .d.ts文件,它们是lib.d.ts或者如果目标是es6,则是lib.es6.d.ts。要扩展全局接口,请创建一个新的 .d.ts 文件,例如myGlobalExtentions.d.ts,并将其包含在您的构建中。

interface Window {
    opera:string;   
}

interface Document {
    documentMode:string;   
}

在我看来,修改WindowDocument的定义并不是一个好主意。这些额外的成员在这里并没有被使用,它们只是被检查以确定浏览器的类型。在这里,使用方括号符号的技巧更加适用。 - Paleo
我同意在这里使用带括号注释的选项1是最好的,只是想演示两个可用的选项。 - Per Svensson
这里的问题是无法通过这种方式解决InstallTrigger。我相信Paleo的答案涵盖了所有的关注点。 - Grungondola

3

现在是2022年; 你可以使用 -

// @ts-ignore

(复制包括//在内的内容)

另请参阅

// @ts-nocheck

在某些情况下可能适用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接