How to extend the 'Window' typescript interface

Ward picture Ward · Jun 21, 2015 · Viewed 20k times · Source

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?"

I'm doing this in VS Code, v.0.3.0 which is running TS v.1.5 (IIRC).

Declaring the interface inside my TS class file where I want to use it doesn't work:

///<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.

Here is "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:

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

Alternatively, I can write an extending interface with another name in my TS class file and then use it in a cast:

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?

Do I really have to go through these gyrations?

Answer

Julian picture Julian · Apr 20, 2017

You need the declare global

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

This works then:

window.fetch('/blah').then(...);