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

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

TypeScript强调MyNamespace,并抱怨:

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

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

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

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

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


当前回答

全局变量是“邪恶的”:)我认为拥有可移植性的最好方法是:

首先导出接口:(例如,./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

第二,导入

import {CustomWindow} from './custom.window.ts';

第三,使用CustomWindow强制转换全局变量窗口:

declare let window: CustomWindow;

通过这种方式,你也不会在不同的IDE中有红线,如果你使用它与窗口对象的存在属性,所以在最后尝试:

window.customAttribute = 'works';
window.location.href = '/works';

用TypeScript 2.4测试。X和最新!

其他回答

今天我想在Angular(6)库中使用它,我花了一段时间才让它像预期的那样工作。

为了使我的库能够使用声明,我必须对声明全局对象的新属性的文件使用d.ts扩展名。

所以最后,这个文件就变成了这样:

/ path-to-angular-workspace / angular-workspace /项目/ angular-library / src / globals.d.ts

创建后,不要忘记在public_api.ts中公开它。

这对我很有帮助。

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

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

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

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

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

还是……

你可以输入:

window['MyNamespace']

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

使用

window["MyNamespace"] = window["MyNamespace"] || {};

应该是正确的,因为它使用了一个字符串属性,但如果你真的想有一个分离的窗口和组织你的代码,你可以扩展窗口对象:

interface MyNamespacedWindow extends Window {
    MyNamespace: object;
}

declare var window: MyNamespacedWindow;
// In typings.d.ts(is Global)
export declare global {
    interface Window {
        __PUBLIC__: string;
    }
}