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

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

TypeScript强调MyNamespace,并抱怨:

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

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

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

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

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


当前回答

接受的答案是我过去使用的,但使用的是TypeScript 0.9。它不再工作了。Window接口的新定义似乎完全取代了内置定义,而不是增强它。

相反,我开始这样做:

interface MyWindow extends Window {
    myFunction(): void;
}

declare var window: MyWindow;

更新:与TypeScript 0.9.5接受的答案再次工作。

其他回答

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

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

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

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

其他大多数答案都不完美。

其中一些只是为了显示而抑制了类型推断。 其他一些只关心全局变量作为名称空间,而不关心接口/类

今天早上我也遇到了一个类似的问题。我在Stack Overflow上尝试了很多“解决方案”,但没有一个完全没有类型错误,并在IDE中启用触发类型跳转(WebStorm或Visual Studio Code)。

最后,从允许模块定义声明为全局变量#3180

我找到了一个合理的解决方案,为同时充当接口/类和名称空间的全局变量附加类型。

例子如下:

// typings.d.ts
declare interface Window {
    myNamespace?: MyNamespace & typeof MyNamespace
}

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

上面的代码将命名空间MyNamespace和接口MyNamespace的类型合并到全局变量MyNamespace (window的属性)中。

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

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

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

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

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

这对我很有帮助。

[2022]:我们必须在React或Nextjs项目中扩展“window”对象。 我们可以通过下面的步骤来解决这个问题。

在src文件夹名称中创建一个文件夹作为类型。 在类型文件夹中创建一个名为index.d.ts的文件 将这段代码写在index.d.ts文件中。 出口{}; 声明全局{ 窗口{ 名称空间:任何; } } 窗口。名称空间=窗口。名称空间| | {};

保存该文件。

现在最后一个变化。

修改“tsConfig. conf”json文件。来继承节点模块类型和我们的类型。

{
  "compilerOptions": {
   ...
    "typeRoots": [
      "./node_modules/@types",
      "./src/types"
    ],
 ....
}

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

首先导出接口:(例如,./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和最新!