typescript 如何扩展“窗口”打字稿界面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30960386/
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 to extend the 'Window' typescript interface
提问by Ward
In my example, I'm trying to extend the TS Window interface to include a polyfill for fetch
. Why doesn't matter. The question is "how do I tell TS that window.fetch
is a valid function?"
在我的示例中,我试图扩展 TS Window 界面以包含fetch
. 为什么无所谓。问题是“我如何告诉 TS 这window.fetch
是一个有效的函数?”
I'm doing this in VS Code, v.0.3.0 which is running TS v.1.5 (IIRC).
我正在运行 TS v.1.5 (IIRC) 的 VS Code v.0.3.0 中执行此操作。
Declaring the interface inside my TS class file where I want to use it doesn't work:
在我要使用它的 TS 类文件中声明接口不起作用:
///<reference path="typings/tsd.d.ts"/>
interface Window {
fetch:(url: string, options?: {}) => Promise<any>
}
...
window.fetch('/blah').then(...); // TS objects that window doesn't have fetch
But it's OK if I declare this same interface in a separate ".d.ts" file and reference it in my TS class file.
但是,如果我在单独的“.d.ts”文件中声明这个相同的接口并在我的 TS 类文件中引用它,那就没问题了。
Here is "typings/window.extend.d.ts"
这是“typings/window.extend.d.ts”
///<reference path="es6-promise/es6-promise"/>
interface Window {
fetch:(url: string, options?: {}) => Promise<any>
}
Now I can use it in my TS class file:
现在我可以在我的 TS 类文件中使用它:
///<reference path="typings/window.extend.d.ts"/>
...
window.fetch('/blah').then(...); // OK
Alternatively, I can write an extending interface with another namein my TS class file and then use it in a cast:
或者,我可以在我的 TS 类文件中用另一个名称编写一个扩展接口,然后在强制转换中使用它:
interface WindowX extends Window {
fetch:(url: string, options?: {}) => Promise<any>
}
...
(<WindowX> window).fetch('/blah').then(...); // OK
Why does extending the interface work in a "d.ts" but not in situ?
为什么扩展接口在“d.ts”中工作而不是在原地工作?
Do I really have to go through these gyrations?
我真的必须经历这些轮回吗?
回答by Julian
You need the declare global
你需要 declare global
declare global {
interface Window {
fetch:(url: string, options?: {}) => Promise<any>
}
}
This works then:
这将起作用:
window.fetch('/blah').then(...);
回答by Ryan Cavanaugh
When you have a top-level import
or export
in your file (which you must somewhere to be having this problem), your file is an external module.
当您有顶级import
或export
在您的文件中(您必须在某个地方遇到此问题)时,您的文件就是一个外部模块。
In an external module, declaring an interface always creates a new type rather than augmenting an existing global interface. This mimics the general behavior of module loaders -- that things declared in this file don't merge or interfere with things in the global scope.
在外部模块中,声明一个接口总是会创建一个新类型,而不是扩充现有的全局接口。这模仿了模块加载器的一般行为——在这个文件中声明的东西不会合并或干扰全局范围内的东西。
The reason for this gyration is that otherwise there wouldn't be a way to, in an external module, define new variables or types with the same name as those in the global scope.
这种循环的原因是,否则将无法在外部模块中定义与全局作用域中名称相同的新变量或类型。