我通过显式设置属性来为我的对象设置全局命名空间 window.

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

TypeScript 下划线 MyNamespace 并抱怨说:

属性“ mynamespace”不存在于类型的“窗口”的价值上

我可以通过声明使代码工作 MyNamespace 作为环境变量并删除 window 明确,但我不想这样做。

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

我怎样才能保留 window 在那里并让 TypeScript 高兴?

顺便说一句,我发现 TypeScript 的抱怨特别有趣,因为它告诉我 window 属于类型 any 其中绝对可以包含任何东西。

有帮助吗?

解决方案

刚刚找到了这个问题的答案 另一个 StackOverflow 问题的答案.

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

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

基本上你需要扩展现有的 window 界面告诉它你的新属性。

其他提示

为了保持动态,只需使用:

(<any>window).MyNamespace

自 Typescript ^3.4.3 起,此解决方案不再有效

或者...

您只需输入:

window['MyNamespace']

你不会得到编译错误,它的工作原理与键入相同 window.MyNamespace

使用多伦多证券交易所?其他答案都不适合我。

这就是我所做的:

(window as any).MyNamespace

接受的答案是我曾经使用过的,但对于 TypeScript 0.9.* 它不再有效。新的定义 Window 接口似乎完全取代了内置定义,而不是增强它。

我已经开始这样做:

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

declare var window: MyWindow;

更新: 在 TypeScript 0.9.5 中,接受的答案再次起作用。

全球都是“邪恶的”:),我认为同时具有可移植性的最佳方法是:

首先导出接口:(例如:./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 和最新版本进行测试!

如果您需要延长 window 具有需要使用的自定义类型的对象 import 您可以使用以下方法:

窗口.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

请参阅手册“声明合并”部分中的“全局增强”: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

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

我只是做了:

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

或者你可以这样做:

let myWindow = window as any;

进而 myWindow.myProp = 'my value';

对于那些使用 角度 CLI 这很简单:

src/polyfills.ts

declare global {
  interface Window {
    myCustomFn: () => void;
  }
}

my-custom-utils.ts

window.myCustomFn = function () {
  ...
};

如果您使用的是 IntelliJ,则还需要在使用新的 polyfill 之前更改 IDE 中的以下设置:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.

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

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

今天早上我也遇到了类似的问题。我在 SO 上尝试了很多“解决方案”,但没有一个绝对不会产生类型错误并在 IDE(webstorm 或 vscode)中启用触发类型跳转。

最后,从这里开始

https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

, ,我找到了一个合理的解决方案 附加全局变量的类型,该变量充当接口/类和命名空间.

示例如下:

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

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

现在,上面的代码合并了命名空间的类型 MyNamespace 和接口 MyNamespace 进入全局变量 myNamespace(窗口的属性)。

在找到答案后,我认为此页面可能会有所帮助。https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation不确定声明合并的历史,但它解释了为什么以下可以起作用。

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

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

如果您正在使用,请按以下步骤操作 TypeScript 定义管理器!

npm install typings --global

创造 typings/custom/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 || {};

如果您使用的是 Typescript 3.x,您可以省略 declare global 参与其他答案,而只需使用:

interface Window {
  someValue: string
  another: boolean
}

当我使用 Typescript 3.3、WebPack 和 TSLint 时,这对我很有用。

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

window["newProperty"] = customObj;

理想情况下,应该避免全局变量的情况。我有时用它来调试浏览器控制台中的对象。

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

里面一个 .d.ts 定义文件

type MyGlobalFunctionType = (name: string) => void

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

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

NodeJS 的想法相同:

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

现在您声明根变量(实际上将存在于窗口或全局变量中)

declare const myGlobalFunction: MyGlobalFunctionType;

然后在常规的 .ts 文件,但作为副作用导入,您实际上实现它:

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

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

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

myGlobalFunction("Kevin");

创建一个自定义界面来扩展窗口并添加您的自定义属性作为可选。

然后,让customWindow使用自定义界面,但以原始窗口赋值。

它与 typescript@3.1.3 一起使用。

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 

对于那些想要设置计算或动态属性的人 window 对象,你会发现这是不可能的 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

为了解决这个问题,您可以采用强制转换的建议 window<any> 所以你可以做

(window as any)[DynamicObject.key]

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

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

所以最后,文件的结果是这样的:

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

创建后,不要忘记将其公开在您的 public_api.ts.

那对我来说是这样的。希望这可以帮助。

首先,您需要在当前范围内声明窗口对象。
因为打字稿想知道对象的类型。
由于窗口对象是在其他地方定义的,因此您无法重新定义它。
但您可以按如下方式声明:-

declare var window: any;

这不会重新定义窗口对象,也不会创建另一个具有名称的变量 window.
这意味着 window 是在其他地方定义的,而您只是在当前范围内引用它。

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

window.MyNamespace

或者您可以将新属性设置为 window 对象只需:-

window.MyNamespace = MyObject

现在打字稿不会抱怨了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top