Как вы явно устанавливаете новое свойство в "window" в TypeScript?
я настраиваю глобальные пространства имен для своих объектов, явно устанавливая свойство на window
.
window.MyNamespace = window.MyNamespace || {};
шрифт подчеркивает MyNamespace
и жалуется, что:
свойство "MyNamespace" не существует для значения типа "window" любой"
Я могу заставить код работать, объявив MyNamespace
как окружающая переменная и падение window
эксплицитности, но я не хочу этого делать.
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
как я могу держать window
там и сделать TypeScript счастливым?
в качестве примечания я нахожу особенно забавным, что TypeScript жалуется, так как он говорит мне, что window
типа any
который определенно может содержать что угодно.
14 ответов
только что нашел ответ на этот вопрос в ответ на другой вопрос StackOverflow.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
в основном вам нужно продлить существующий window
интерфейс, чтобы рассказать ему о Вашем новом свойстве.
или...
вы можете просто ввести:
window['MyNamespace']
и вы не получите ошибку компиляции, и она работает так же, как пишите window.MyNamespace
использование TSX? Ни один из других ответов не работал на меня.
вот что я сделал:
(window as any).MyNamespace
принятый ответ - это то, что я использовал, но с TypeScript 0.9.* он больше не работает. Новое определение Window
интерфейс, похоже, полностью заменяет встроенное определение, а не увеличивает его.
я взялся делать это вместо этого:
interface MyWindow extends Window {
myFunction(): void;
}
declare var window: MyWindow;
обновление: С TypeScript 0.9.5 принятый ответ снова работает.
Если вам нужно продлить window
объект с пользовательским типом, который требует использования import
вы можете использовать следующий метод:
Global-это "зло":), я думаю, что лучший способ иметь также переносимость:
сначала вы экспортируете интерфейс: (например: ./обычай.окно.ts)
export interface CustomWindow extends Window {
customAttribute: any;
}
второй импортировать
import {CustomWindow} from './custom.window.ts';
третье литое глобальное окно var с CustomWindow
declare let window: CustomWindow;
таким образом, у вас нет также красной линии в другой IDE, если вы используете с существующими атрибутами объекта window, поэтому в конце попробуйте:
window.customAttribute = 'works';
window.location.href = '/works';
протестировано с помощью Typescript 2.4.x
вот как это сделать, если вы используете Менеджер Определения TypeScript!
npm install typings --global
создать typings/custom/window.d.ts
:
interface Window {
MyNamespace: any;
}
declare var window: Window;
установите пользовательский ввод:
typings install file:typings/custom/window.d.ts --save --global
готово, используйте его! Typescript больше не будет жаловаться:
window.MyNamespace = window.MyNamespace || {};
большинство других ответов не идеальны.
- некоторые из них просто подавить вывод типа для магазина.
- некоторые из других заботятся только о глобальной переменной как пространстве имен, но не как интерфейс/класс
Я также сталкиваюсь с аналогичной проблемой сегодня утром. Я пробовал так много "решений" на SO, но ни одно из них не дает никакой ошибки типа абсолютно и не позволяет запускать прыжки типа в IDE(webstorm или vscode).
наконец, отсюда
https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512
, Я нахожу разумное решение для прикрепить типы для глобальной переменной, которая действует как интерфейс / класс и пространство имен.
пример ниже:
// typings.d.ts
declare interface Window {
myNamespace?: MyNamespace & typeof MyNamespace
}
declare interface MyNamespace {
somemethod?()
}
declare namespace MyNamespace {
// ...
}
теперь код выше объединяет типы пространства имен MyNamespace
интерфейс MyNamespace
в глобальную переменную myNamespace
(собственность окно.)
мне не нужно делать это очень часто, единственный случай, который у меня был, был при использовании Redux Devtools с middleware.
Я просто сделал:
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
или вы могли бы сделать:
let myWindow = window as any;
а то myWindow.myProp = 'my value';
Если вы используете угловой CLI это действительно просто (протестировано на CLI RC.0):
src / polyfills.ТС
declare global {
interface Window {
myCustomFn: () => void;
}
}
my-custom-utils.ТС
window.myCustomFn = function () {
...
};
Я использую IntelliJ, поэтому мне также нужно было изменить следующую настройку в IDE, прежде чем мои новые polyfills подобрали:
> File
> Settings
> Languages & Frameworks
> TypeScript
> check 'Use TypeScript Service'.
Для справки (это правильный ответ):
внутри .d.ts
файл определения
type MyGlobalFunctionType = (name: string) => void
если вы работаете в браузере, вы добавляете членов в контекст окна браузера, открывая интерфейс окна:
interface Window {
myGlobalFunction: MyGlobalFunctionType
}
та же идея для NodeJS:
declare module NodeJS {
interface Global {
myGlobalFunction: MyGlobalFunctionType
}
}
теперь вы объявляете корневую переменную (которая фактически будет жить в window или global)
declare const myGlobalFunction: MyGlobalFunctionType;
тогда в обычном .ts
файл, но импортированный как побочный эффект, вы на самом деле реализовать это:
global/* or window */.myGlobalFunction = function (name: string) {
console.log("Hey !", name);
};
и, наконец, использовать его в другом месте в базе кода, либо:
global/* or window */.myGlobalFunction("Kevin");
myGlobalFunction("Kevin");
после поиска ответов вокруг, я думаю, что эта страница может быть полезна. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Не уверен в истории слияния деклараций, но это объясняет, почему может работать следующее.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
Я хотел использовать это в угловой (6) библиотеке сегодня, и мне потребовалось некоторое время, чтобы заставить это работать, как ожидалось.
для того, чтобы моя библиотека использовала объявления, я должен был использовать d.ts
расширение файла, объявляющего новые свойства глобального объекта.
Итак, в конце концов, файл закончился чем-то вроде:
/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts
после создания, не забудьте выставить его в вашем public_api.ts
.
Это сделало это для меня. Надеюсь, это поможет.