如何扩展'Window'打字稿界面

War*_*ard 20 typescript typescript1.5 fetch-api

在我的例子中,我正在尝试扩展TS Window接口以包含polyfill fetch.为什么无所谓.问题是" 我怎么告诉TS这window.fetch是一个有效的函数? "

我在运行TS v.1.5(IIRC)的VS Code,v.0.3.0中这样做.

在我想要使用它的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
Run Code Online (Sandbox Code Playgroud)

但是如果我在一个单独的".d.ts"文件中声明这个相同的接口并在我的TS类文件中引用它,那就没关系.

这是"typings/window.extend.d.ts"

///<reference path="es6-promise/es6-promise"/>
interface Window {
  fetch:(url: string, options?: {}) => Promise<any>
}
Run Code Online (Sandbox Code Playgroud)

现在我可以在我的TS类文件中使用它:

///<reference path="typings/window.extend.d.ts"/>
...
window.fetch('/blah').then(...); // OK
Run Code Online (Sandbox Code Playgroud)

或者,我可以在我的TS类文件中使用另一个名称编写扩展接口,然后在强制转换中使用它:

interface WindowX extends Window {
  fetch:(url: string, options?: {}) => Promise<any>
}
...
(<WindowX> window).fetch('/blah').then(...); // OK
Run Code Online (Sandbox Code Playgroud)

为什么扩展接口工作在"d.ts"而不是就地

我真的必须经历这些旋转吗?

Jul*_*ian 19

你需要的 declare global

declare global {
  interface Window {
    fetch:(url: string, options?: {}) => Promise<any>
  }
}
Run Code Online (Sandbox Code Playgroud)

这适用于:

window.fetch('/blah').then(...); 
Run Code Online (Sandbox Code Playgroud)


Rya*_*ugh 15

当您有一个顶级importexport您的文件(您必须在某处遇到此问题)时,您的文件是外部模块.

在外部模块中,声明接口始终会创建新类型,而不是扩充现有的全局接口.这模仿了模块加载器的一般行为 - 在此文件中声明的内容不会合并或干扰全局范围内的事物.

这种回转的原因在于,否则将无法在外部模块中定义与全局范围中的变量或类型具有相同名称的新变量或类型.

  • 当它们准确时,我们喜欢打字.当他们不是时,我们厌恶他们.有一条干净的道路来扩展它们很重要.我也想知道其他选择 (4认同)
  • 可以从外部模块中扩展“window”对象。在此处查看我的答案:http://stackoverflow.com/a/40204572/274837 (2认同)