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

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是一样的。

其他回答

对于那些想要在窗口对象上设置计算或动态属性的人,你会发现使用declare global方法是不可能的。来阐明这个用例

window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature

你可以尝试这样做

declare global {
  interface Window {
    [DyanmicObject.key]: string; // error RIP
  }
}

但上面的操作会出错。这是因为在TypeScript中,接口不能很好地使用计算属性,并且会抛出类似于

A computed property name in an interface must directly refer to a built-in symbol

为了解决这个问题,你可以按照建议将窗口转换为<any>

(window as any)[DynamicObject.key]

首先,您需要在当前 范围。因为TypeScript想知道对象的类型 对象。由于窗口对象是在其他地方定义的,所以不能重新定义它。

但你可以按以下方式申报:

declare var window: any;

这将不会重新定义窗口对象,也不会创建另一个名为window的变量。这意味着窗口是在其他地方定义的,您只是在当前作用域中引用它。

然后你可以通过以下方式引用你的MyNamespace对象:

window.MyNamespace

或者你可以在窗口对象上简单地设置新属性:

window.MyNamespace = MyObject

现在TypeScript不会抱怨了。

从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。

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

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

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

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

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

这对我很有帮助。

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

interface Window {
    MyNamespace: any;
}