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

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

TypeScript强调MyNamespace,并抱怨:

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

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

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

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

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


当前回答

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

interface Window {
  someValue: string
  another: boolean
}

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

其他回答

我不需要经常这样做。我唯一遇到的情况是在中间件中使用Redux DevTools。

我只是做了:

const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

或者你可以这样做:

let myWindow = window as any;

然后是myWindow。myProp = '我的值';

对于那些使用Angular CLI的人来说,这很简单:

文件src / polyfills.ts

declare global {
  interface Window {
    myCustomFn: () => void;
  }
}

文件my-custom-utils.ts

window.myCustomFn = function () {
  ...
};

如果你正在使用IntelliJ IDEA,你还需要在IDE中更改以下设置,然后你的新腻子才会开始:

> File
> Settings
> Languages & Frameworks
> TypeScript
> check 'Use TypeScript Service'.

如果您需要使用需要使用import的自定义类型来扩展窗口对象,您可以使用以下方法:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

请参阅手册的“声明合并”部分中的全局增强。

要保持动态,只需使用:

(<any>window).MyNamespace

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

从TypeScript ^3.4.3开始,这个解决方案不再有效

还是……

你可以输入:

window['MyNamespace']

你不会得到一个编译错误它和输入window。mynamespace是一样的。