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?
You need the declare global
declare global {
interface Window {
fetch:(url: string, options?: {}) => Promise<any>
}
}
This works then:
window.fetch('/blah').then(...);