你如何在 TypeScript 的 `window` 上显式设置一个新属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12709074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you explicitly set a new property on `window` in TypeScript?
提问by joshuapoehls
I setup global namespaces for my objects by explicitly setting a property on window
.
我通过在 上显式设置属性来为我的对象设置全局命名空间window
。
window.MyNamespace = window.MyNamespace || {};
TypeScript underlines MyNamespace
and complains that:
TypeScript 强调MyNamespace
并抱怨:
The property 'MyNamespace' does not exist on value of type 'window' any"
属性 'MyNamespace' 不存在于类型为 'window' any 的值上"
I can make the code work by declaring MyNamespace
as an ambient variable and dropping the window
explicitness but I don't want to do that.
我可以通过声明MyNamespace
为环境变量并删除window
显式来使代码工作,但我不想这样做。
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
How can I keep window
in there and make TypeScript happy?
我怎样才能window
留在那里并使 TypeScript 开心?
As a side note I find it especially funny that TypeScript complains since it tells me that window
is of type any
which by definitely can contain anything.
作为旁注,我发现 TypeScript 抱怨特别有趣,因为它告诉我它window
的类型any
绝对可以包含任何内容。
回答by joshuapoehls
Just found the answer to this in another StackOverflow question's answer.
刚刚在另一个 StackOverflow 问题的答案中找到了答案。
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
Basically you need to extend the existing window
interface to tell it about your new property.
基本上你需要扩展现有的window
接口来告诉它你的新属性。
回答by chinupson
To keep it dynamic, just use:
要保持动态,只需使用:
(<any>window).MyNamespace
回答by Evan Larsen
AS OF TYPESCRIPT ^3.4.3 THIS SOLUTION NO LONGER WORKS
从 TYPESCRIPT ^3.4.3 开始,此解决方案不再有效
Or...
或者...
you can just type:
你可以输入:
window['MyNamespace']
and you wont get a compile error and it works the same as typing window.MyNamespace
并且您不会收到编译错误,它的工作方式与键入相同 window.MyNamespace
回答by David Boyd
Using TSX? None of the other answers were working for me.
使用多伦多证券交易所?其他答案都不适合我。
Here's what I did:
这是我所做的:
(window as any).MyNamespace
回答by Blake Mitchell
The accepted answer is what I used to use, but with TypeScript 0.9.* it no longer works. The new definition of the Window
interface seems to completely replace the built-in definition, instead of augmenting it.
接受的答案是我以前使用的答案,但使用 TypeScript 0.9.* 它不再有效。Window
接口的新定义似乎完全取代了内置定义,而不是对其进行了扩充。
I have taken to doing this instead:
我已经开始这样做了:
interface MyWindow extends Window {
myFunction(): void;
}
declare var window: MyWindow;
UPDATE:With TypeScript 0.9.5 the accepted answer is working again.
更新:使用 TypeScript 0.9.5,接受的答案再次起作用。
回答by onalbi
Global are "evil" :), i think the best way to have also the portability is:
全局是“邪恶的”:),我认为同时具有可移植性的最佳方法是:
First you export the interface: (eg: ./custom.window.ts)
首先导出界面:(例如:./custom.window.ts)
export interface CustomWindow extends Window {
customAttribute: any;
}
Second you import
第二次导入
import {CustomWindow} from './custom.window.ts';
Third cast global var window with CustomWindow
使用 CustomWindow 进行第三次强制转换全局变量窗口
declare let window: CustomWindow;
In this way you don't have also red line in different IDE if you use with existent attributes of window object, so at the end try:
通过这种方式,如果您使用 window 对象的现有属性,则在不同的 IDE 中也不会出现红线,因此最后尝试:
window.customAttribute = 'works';
window.location.href = '/works';
Tested with Typescript 2.4.x and newest!
使用 Typescript 2.4.x 和最新版本进行测试!
回答by Lucifer Sam
If you need to extend the window
object with a custom type that requires the use of import
you can use the following method:
如果您需要window
使用需要使用的自定义类型扩展对象,import
可以使用以下方法:
window.d.ts
窗口.d.ts
import MyInterface from './MyInterface';
declare global {
interface Window {
propName: MyInterface
}
}
See 'Global Augmentation' in the 'Declaration Merging' section of the Handbook: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
请参阅手册“声明合并”部分中的“全局增强”:https: //www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
回答by Stephen Paul
For those using the Angular CLIit's straightforward:
对于那些使用Angular CLI 的人来说,这很简单:
src/polyfills.ts
src/polyfills.ts
declare global {
interface Window {
myCustomFn: () => void;
}
}
my-custom-utils.ts
我的自定义utils.ts
window.myCustomFn = function () {
...
};
If you're using IntelliJ, you also needed to change the following setting in the IDE before your new polyfills pick up:
如果您使用的是 IntelliJ,则还需要在新的 polyfill 启动之前更改 IDE 中的以下设置:
> File
> Settings
> Languages & Frameworks
> TypeScript
> check 'Use TypeScript Service'.
回答by Dimitar Nikovski
I don't need to do this very often, the only case I have had was when using Redux Devtools with middleware.
我不需要经常这样做,我遇到的唯一情况是将 Redux Devtools 与中间件一起使用。
I simply did:
我只是做了:
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
Or you could do:
或者你可以这样做:
let myWindow = window as any;
let myWindow = window as any;
and then myWindow.myProp = 'my value';
进而 myWindow.myProp = 'my value';
回答by e-cloud
Most of the other answers are not perfect.
大多数其他答案并不完美。
- Some of them just suppress the type inference for shop.
- Some of the others only cares about global variable as namespace, but not as interface/class
- 其中一些只是抑制商店的类型推断。
- 其他一些只关心作为命名空间的全局变量,而不关心作为接口/类
I also encounter the similar problem this morning. I tried so many "solutions" on SO, but none of them produce no type error absolutely and enable triggering type jumping in IDE(webstorm or vscode).
我今天早上也遇到了类似的问题。我在 SO 上尝试了很多“解决方案”,但没有一个绝对不会产生类型错误,并在 IDE(webstorm 或 vscode)中启用触发类型跳转。
Finally, from here
最后,从这里
https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512
https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512
, I find a reasonable solution to attach typings for global variable which acts as interface/class and namespace both.
,我找到了一个合理的解决方案来附加作为接口/类和命名空间的全局变量的类型。
Example is below:
示例如下:
// typings.d.ts
declare interface Window {
myNamespace?: MyNamespace & typeof MyNamespace
}
declare interface MyNamespace {
somemethod?()
}
declare namespace MyNamespace {
// ...
}
Now, the code above merges the typings of namespace MyNamespace
and interface MyNamespace
into the global variable myNamespace
(the property of window).
现在,上面的代码将命名空间MyNamespace
和接口的类型MyNamespace
合并到全局变量myNamespace
(window 的属性)中。