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

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

TypeScript强调MyNamespace,并抱怨:

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

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

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

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

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


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

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

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

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

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

还是……

你可以输入:

window['MyNamespace']

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

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

相反,我开始这样做:

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

declare var window: MyWindow;

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

要保持动态,只需使用:

(<any>window).MyNamespace

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

使用slvelte还是TSX?其他的答案都对我不起作用。

以下是我所做的:

(window as any).MyNamespace

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

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

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

下面是如何做到这一点,如果你使用的是TypeScript定义管理器!

npm install typings --global

创建输入/定制/ window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

安装自定义输入:

typings install file:typings/custom/window.d.ts --save --global

完成了!使用它!TypeScript不会再抱怨了:

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

在四处寻找答案后,我认为这个页面可能会有所帮助:

全球增长

我不确定声明合并的历史,但它解释了为什么下面可以工作。

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

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

对于那些使用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'.

供参考(这是正确答案):

在。d里面。Ts定义文件

type MyGlobalFunctionType = (name: string) => void

如果你在浏览器中工作,你可以通过重新打开window的界面将成员添加到浏览器的窗口上下文:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Node.js也是这样:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}

现在你声明根变量(它将实际存在于window或global上):

declare const myGlobalFunction: MyGlobalFunctionType;

然后在一个普通的.ts文件中,但作为副作用导入,你实际上实现了它:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};

最后在代码库的其他地方使用它,使用:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");

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

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

今天早上我也遇到了一个类似的问题。我在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的属性)中。

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

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

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

我只是做了:

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

或者你可以这样做:

let myWindow = window as any;

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

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

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

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

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

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

这对我很有帮助。

创建一个扩展Window的自定义界面,并将自定义属性添加为可选属性。

然后,让customWindow使用自定义接口,但值与原始窗口相同。

它与TypeScript 3.1.3一起工作。

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {}

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

interface Window {
  someValue: string
  another: boolean
}

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

对于那些想要在窗口对象上设置计算或动态属性的人,你会发现使用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不会抱怨了。

TypeScript不会对字符串属性执行类型检查。

window["newProperty"] = customObj;

理想情况下,应该避免使用全局变量场景。我有时使用它在浏览器控制台中调试一个对象。

创建一个名为global.d的文件。Ts,例如/src/@types/global.d。Ts,然后定义如下接口:

interface Window {
  myLib: any
}

参考:Global .d.ts

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

interface Window {
    MyNamespace: any;
}

使用

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

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

interface MyNamespacedWindow extends Window {
    MyNamespace: object;
}

declare var window: MyNamespacedWindow;

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

window?.MyNamespace =  'value'

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

完整和简短的回答

1-在tsconfig.json中添加typeRoots属性:

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

2-扩展窗口类型

// file: src/@types/global.d.ts

declare global {
    interface Window { customProperty: <type>; }
}
(window as { test: string } & Window & typeof globalThis).test = `Hello World`;
// In typings.d.ts(is Global)
export declare global {
    interface Window {
        __PUBLIC__: string;
    }
}

我使用无声明。 我的例子如下:

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

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

保存该文件。

现在最后一个变化。

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

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