Как расширить интерфейс "Window" typescript
В моем примере я пытаюсь расширить интерфейс TS Window, чтобы включить polyfill для fetch
. Почему не имеет значения. Вопрос: ", как я могу сказать TS, что window.fetch
является допустимой функцией?"
Я делаю это в VS Code, v.0.3.0, который запускает TS v.1.5 (IIRC).
Объявление интерфейса внутри моего файла 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-класса.
Вот "typings/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", но не на месте?
Должен ли я действительно пройти эти вращения?
Ответы
Ответ 1
Если в вашем файле есть верхний уровень import
или export
(который должен где-то возникнуть с такой проблемой), ваш файл является внешним модулем.
Во внешнем модуле объявление интерфейса всегда создает новый тип, а не расширяет существующий глобальный интерфейс. Это имитирует общее поведение загрузчиков модулей - что вещи, объявленные в этом файле, не сливаются и не мешают вещам в глобальной области.
Причиной этого gyration является то, что в противном случае во внешнем модуле не было бы способа определить новые переменные или типы с тем же именем, что и в глобальной области.
Ответ 2
Вам понадобится declare global
declare global {
interface Window {
fetch:(url: string, options?: {}) => Promise<any>
}
}
Это работает тогда:
window.fetch('/blah').then(...);