我通过显式设置窗口上的属性为我的对象设置全局名称空间。

window.MyNamespace = window.MyNamespace || {};

TypeScript强调MyNamespace,并抱怨:

属性“MyNamespace”在类型为“window”的值上不存在 任何“

我可以通过将MyNamespace声明为环境变量并删除窗口显式来使代码工作,但我不想这样做。

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

我如何保持窗口在那里,让TypeScript满意?

作为旁注,我发现特别有趣的是,TypeScript抱怨,因为它告诉我,窗口的类型是any,它肯定可以包含任何东西。


当前回答

TypeScript阻止在没有指定具有所需属性或类型的情况下访问对象 已经分配给了any,所以你可以使用可选的链接:

window?.MyNamespace =  'value'

其他回答

如果你使用的是TypeScript 3。X,你可以在其他答案中省略声明全局部分,而只是使用:

interface Window {
  someValue: string
  another: boolean
}

当我使用TypeScript 3.3、Webpack和TSLint时,这种方法很有效。

我刚刚在另一个Stack Overflow问题的答案中找到了这个问题的答案。

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};

基本上,您需要扩展现有的窗口界面来告诉它您的新属性。

使用create-react-app v3.3,我发现实现这一点最简单的方法是扩展自动生成的react-app-env.d.ts中的Window类型:

interface Window {
    MyNamespace: any;
}

要保持动态,只需使用:

(<any>window).MyNamespace

注意,这可能不适用于TSX,因为编译器可能认为<any>是TSX元素。查看与TSX兼容的类型断言的答案。

创建一个名为global.d的文件。Ts,例如/src/@types/global.d。Ts,然后定义如下接口:

interface Window {
  myLib: any
}

参考:Global .d.ts