Я устанавливаю глобальные пространства имен для своих объектов, явно устанавливая свойство на window
.
window.MyNamespace = window.MyNamespace || {};
TypeScript подчеркивает MyNamespace
и жалуется, что:
Свойство 'MyNamespace' не существует при значении типа 'window' любой "
Я могу заставить код работать, объявив MyNamespace
в качестве переменной окружения и отбрасывая window
эксплицитно, но я не хочу этого делать.
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
Как я могу сохранить window
там и сделать TypeScript счастливым?
В качестве побочного примечания мне особенно забавно, что TypeScript жалуется, так как он говорит мне, что window
имеет тип any
, который определенно может содержать что угодно.
Просто нашел ответ на этот вопрос в https://stackoverflow.com/questions/12703266/how-to-handle-warnings-for-proprietary-custom-properties-of-built-in-objects-in.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
В основном вам необходимо расширить существующий интерфейс window
, чтобы рассказать об этом новом свойстве.
Чтобы сохранить динамику, просто используйте:
(<any>window).MyNamespace
Или...
вы можете просто ввести:
window['MyNamespace']
и вы не получите ошибку компиляции, и она будет работать так же, как набирать window.MyNamespace
Использование TSX? Ни один из других ответов не работал на меня.
Вот что я сделал:
(window as any).MyNamespace
(<any> window).MyNamespace
самом деле (<any> window).MyNamespace
<any>
интерпретируется как JSX, а не как приведение типа.
Принятый ответ - это то, что я использовал, но с TypeScript 0.9. * он больше не работает. Новое определение интерфейса Window
похоже, полностью заменяет встроенное определение, а не увеличивает его.
Вместо этого я сделал это:
interface MyWindow extends Window {
myFunction(): void;
}
declare var window: MyWindow;
ОБНОВЛЕНИЕ: С TypeScript 0.9.5 принятый ответ снова работает.
export default class MyClass{ foo(){ ... } ... }
interface MyWindow extends Window{ mc: MyClass }
declare var window: MyWindow
window.mc = new MyClass()
Затем вы можете вызвать foo (), например, из консоль Chrome Dev Tools, например mc.foo()
declare var...
в каждом файле, который вам нужен.
Если вам нужно расширить объект window
с помощью специального типа, который требует использования import
, вы можете использовать следующий метод:
window.d.ts
import MyInterface from './MyInterface';
declare global {
interface Window {
propName: MyInterface
}
}
См. "Глобальное увеличение" в разделе "Объединение декларации" Справочника: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
Глобальные "злые":), я думаю, что лучший способ иметь мобильность:
Сначала вы экспортируете интерфейс: (например:./custom.window.ts)
export interface CustomWindow extends Window {
customAttribute: any;
}
Во-вторых, вы импортируете
import {CustomWindow} from './custom.window.ts';
Третье глобальное окно var cast с CustomWindow
declare let window: CustomWindow;
Таким образом, у вас нет также красной линии в разных IDE, если вы используете с существующими атрибутами объекта window, поэтому в конце попробуйте:
window.customAttribute = 'works';
window.location.href = '/works';
Протестировано с помощью Typescript 2.4.x
Мне не нужно делать это очень часто, единственный случай, который у меня был, был при использовании Redux Devtools с промежуточным программным обеспечением.
Я просто сделал:
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
Или вы могли бы сделать:
let myWindow = window as any;
а затем myWindow.myProp = 'my value';
Большинство других ответов не являются идеальными.
Я также сталкиваюсь с подобной проблемой этим утром. Я пробовал так много "решений" на 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
(свойство window).
Здесь, как это сделать, если вы используете 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 || {};
typings
устарело в Typescript 2.0 (середина 2016 года) и было заархивировано владельцем.
Если вы используете Angular CLI, это действительно просто:
SRC/polyfills.ts
declare global {
interface Window {
myCustomFn: () => void;
}
}
мой-таможенно-utils.ts
window.myCustomFn = function () {
...
};
Если вы используете IntelliJ, вам также необходимо изменить следующие настройки в IDE, прежде чем ваши новые полифиллы будут загружены:
> File
> Settings
> Languages & Frameworks
> TypeScript
> check 'Use TypeScript Service'.
После поиска ответов, я думаю, что эта страница может быть полезной. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Не уверен насчет истории слияния объявлений, но он объясняет, почему может работать следующее.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
Для справки (это правильный ответ):
Внутри файла определения .d.ts
type MyGlobalFunctionType = (name: string) => void
Если вы работаете в браузере, вы добавляете участников в контекст окна браузера, открывая интерфейс Window:
interface Window {
myGlobalFunction: MyGlobalFunctionType
}
Такая же идея для NodeJS:
declare module NodeJS {
interface Global {
myGlobalFunction: MyGlobalFunctionType
}
}
Теперь вы объявляете корневую переменную (которая фактически будет жить в окне или глобальном)
declare const myGlobalFunction: MyGlobalFunctionType;
Затем в регулярном файле .ts
, но импортированном как побочный эффект, вы фактически реализуете его:
global/* or window */.myGlobalFunction = function (name: string) {
console.log("Hey !", name);
};
И, наконец, используйте его в другом месте в базе кода: либо
global/* or window */.myGlobalFunction("Kevin");
myGlobalFunction("Kevin");
Создание настраиваемого интерфейса расширяет окно и добавляет ваше настраиваемое свойство как необязательное.
Затем позвольте customWindow, использующему пользовательский интерфейс, но оцененному с помощью исходного окна.
Он работал с [email protected].
interface ICustomWindow extends Window {
MyNamespace?: any
}
const customWindow:ICustomWindow = window;
customWindow.MyNamespace = customWindow.MyNamespace {}
Я хотел использовать это в библиотеке Angular (6) сегодня, и мне потребовалось некоторое время, чтобы заставить это работать как ожидалось.
Чтобы моя библиотека использовала объявления, мне пришлось использовать расширение d.ts
для файла, который объявляет новые свойства глобального объекта.
Итак, в конце концов, файл закончился чем-то вроде:
/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts
После создания не забудьте выставить его в свой public_api.ts
.
Это сделало это для меня. Надеюсь это поможет.
Когда я попробовал это, window
набрал значение window
- это означает, что есть определение, которое указывает, какие свойства и методы поддерживает window
, а ваше собственное пространство имен отсутствует в этом списке.
Не можете ли вы получить нужное поведение с помощью модуля TypeScript?
module MyNamespace {
export class Example {
}
}