36

在我的示例中,我正在尝试扩展 TS Window 接口以包含用于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

但是如果我在一个单独的“.d.ts”文件中声明这个相同的接口并在我的 TS 类文件中引用它就可以了。

这是“打字/window.extend.d.ts”

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

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

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

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

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

为什么扩展接口在“d.ts”中工作而不是原位

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

4

2 回答 2

41

你需要declare global

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

这有效:

window.fetch('/blah').then(...); 
于 2017-04-20T08:07:58.047 回答
20

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

在外部模块中,声明接口总是创建一个新类型,而不是扩充现有的全局接口。这模仿了模块加载器的一般行为——在这个文件中声明的东西不会合并或干扰全局范围内的东西。

这种旋转的原因是,否则将无法在外部模块中定义与全局范围内同名的新变量或类型。

于 2015-06-21T04:41:13.423 回答