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

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

TypeScript强调MyNamespace,并抱怨:

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

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

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

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

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


当前回答

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

还是……

你可以输入:

window['MyNamespace']

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

其他回答

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

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

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

(window as { test: string } & Window & typeof globalThis).test = `Hello World`;

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

interface Window {
    MyNamespace: any;
}

从3.4版开始,TypeScript已经支持globalThis。参见globalThis的类型检查。

从上面的链接:

// in a global file:
var abc = 100;
// Refers to 'abc' from above.
globalThis.abc = 200;
window.abc = 300; // window object can also be used.

操场上

“全局”文件是没有任何导入/导出语句的文件。声明var abc;可以写成。d.ts。

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

window?.MyNamespace =  'value'