Расширить окно с новым свойством [duplicate]

Кажется, что это работает: /(\{(?:\{.*\}|[^\{])*\})/m

298
задан joshuapoehls 3 October 2012 в 14:01
поделиться

14 ответов

Просто нашел ответ на этот вопрос в ответе на вопрос другого пользователя StackOverflow .

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};

В основном вам нужно расширить существующий интерфейс window, чтобы рассказать об этом новом свойстве .

260
ответ дан Luke 21 August 2018 в 16:52
поделиться
  • 1
    не работает с текущей версией машинописного текста. – citykid 1 April 2013 в 18:24
  • 2
    Обратите внимание на столицу W в окне. Это сбило меня с толку. – ajm 9 October 2013 в 21:55
  • 3
    Я не мог заставить это скомпилировать с tsc 1.0.1.0. Ответ Блейка Митчелла действительно работал для меня. – Pat 13 October 2014 в 18:51
  • 4
    Имейте в виду, что это работает только при объявлении в отдельном файле .d.ts. Он не работает при использовании в файле .ts, который использует импорт и экспорт. См. этот ответ . – cdauth 9 March 2016 в 15:21
  • 5
    declare global { interface Window { ... } } работает с TypeScript 2.5.2, нет необходимости в файле .d.ts, как указано выше – tanguy_k 3 September 2017 в 20:29

Для справки (это правильный ответ):

Внутри файла определения .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");
2
ответ дан Benoit B. 21 August 2018 в 16:52
поделиться

Принятый ответ - это то, что я использовал, но с TypeScript 0.9. * он больше не работает. Новое определение интерфейса Window, по-видимому, полностью заменяет встроенное определение, а не увеличивать его.

Я решил сделать это вместо:

interface MyWindow extends Window {
    myFunction(): void;
}

declare var window: MyWindow;

UPDATE : С TypeScript 0.9.5 принятый ответ снова работает.

47
ответ дан Blake Mitchell 21 August 2018 в 16:52
поделиться
  • 1
    Это работает также с модулями, используемыми TypeScript 2.0.8. Пример: 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() – Martin Majewski 5 December 2016 в 17:43
  • 2
    Это очень хороший ответ, если вы не хотите объявлять что-то глобальным. С другой стороны, вам нужно вызвать declare var... в каждом файле, который вам нужен. – Puce 25 May 2018 в 12:23
  • 3
    – Dmitrii Sorin 4 October 2018 в 06:55

Чтобы сохранить динамику, просто используйте:

(<any>window).MyNamespace
271
ответ дан chinupson 21 August 2018 в 16:52
поделиться
  • 1
    Любые идеи, как это сделать в tsx-файле? – velop 16 March 2017 в 08:06
  • 2
  • 3
    Думаю, это работает без -noImplicitAny ... – martin 18 April 2017 в 19:16
  • 4
    @martin: & lt; any & gt; делает это явным, так что все работает отлично. Другие. Если вы используете TypScript с React или другой средой JSX (в результате чего используется синтаксис TSX), вам придется использовать as вместо <>. См. Ответ @ david-boyd's ниже . – Don 22 August 2017 в 15:59
  • 5
    Мне пришлось использовать (окно как любое) .MyNamespace – ArsalanDotMe 19 September 2017 в 09:37

Использование TSX? Ни один из других ответов не работал на меня.

Вот что я сделал:

(window as any).MyNamespace
99
ответ дан David Boyd 21 August 2018 в 16:52
поделиться

Мне не нужно делать это очень часто, единственный случай, который у меня был, - это использовать Redux Devtools со средним программным обеспечением.

Я просто сделал:

const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

Или вы можете сделать:

let myWindow = window as any;

, а затем myWindow.myProp = 'my value';

6
ответ дан Dimitar Nikovski 21 August 2018 в 16:52
поделиться

Я хотел использовать это в библиотеке Angular (6) сегодня, и мне потребовалось некоторое время, чтобы это работало, как ожидалось.

Чтобы моя библиотека использовала объявления, мне пришлось использовать расширение d.ts для файла, объявляющего новые свойства глобального объекта.

Итак, в конце файл получил что-то вроде:

/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts

После создания не забудьте выставить его в своем public_api.ts.

Это сделало это для меня. Надеюсь, это поможет.

2
ответ дан Dirk 21 August 2018 в 16:52
поделиться

Большинство других ответов не идеальны.

  • Некоторые из них просто подавляют вывод типа для магазина.
  • Некоторые из других заботятся только о глобальной переменной как пространство имен, но не как интерфейс / класс

Я также сталкиваюсь с аналогичной проблемой сегодня утром. Я пробовал так много «решений» на 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 (свойство окна).

6
ответ дан e-cloud 21 August 2018 в 16:52
поделиться
  • 1
    Спасибо - это единственный, который вы можете использовать в окружающем немодульном контексте. – Tyler Sebastian 26 July 2017 в 23:31

Или ...

вы можете просто набрать:

window['MyNamespace']

, и вы не получите ошибку компиляции, и она будет работать так же, как и набрав window.MyNamespace

137
ответ дан Evan Larsen 21 August 2018 в 16:52
поделиться
  • 1
    но вы, вероятно, получите ошибку tslint ... Если у вас есть, конечно, – smnbbrv 7 January 2016 в 13:34
  • 2
    Это полностью летит перед лицом сильной типизации, всей идеи, лежащей в основе TypeScript. – d512 29 January 2016 в 00:55
  • 3
    @ user1334007 использование globals делает. Однако некоторые устаревшие коды требуют этого. – nathancahill 1 March 2016 в 18:03
  • 4
    @ user1334007 это пример, когда вам нужен этот материал: andrewhfarmer.com/aws-sdk-with-webpack – SMSk 5 December 2016 в 16:18
  • 5
    @Ramesh window['MyNamespace']() (просто добавьте скобки) – iBaff 21 December 2017 в 19:14

Если вам нужно расширить объект 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

29
ответ дан Lucifer Sam 21 August 2018 в 16:52
поделиться

Вот как это сделать, если вы используете TypeScript Definition Manager !

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

Сделано, используйте его & zwnj; ! Тип машинописного текста больше не будет жаловаться:

window.MyNamespace = window.MyNamespace || {};
8
ответ дан Nik Sumeiko 21 August 2018 в 16:52
поделиться

После поиска ответов, я думаю, эта страница может быть полезна. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Не уверен в истории слияния декларации, но это объясняет, почему следующее может работать.

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};
2
ответ дан Sagar Kharche 21 August 2018 в 16:52
поделиться

Если вы используете Angular CLI, это очень просто (проверено на CLI RC.0):

src / polyfills.ts

declare global {
  interface Window {
    myCustomFn: () => void;
  }
}

my-custom-utils .ts

window.myCustomFn = function () {
  ...
};

Я использую IntelliJ, поэтому мне также нужно было изменить следующую настройку в среде IDE до того, как мои новые полипы забрали:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
5
ответ дан Stephen Paul 21 August 2018 в 16:52
поделиться

Глобальные «злые» :), я думаю, что лучший способ иметь и переносимость:

Сначала вы экспортируете интерфейс: (например: ./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.customAttribute = 'works';
window.location.href = '/works';

Протестировано с помощью TypScript 2.4.x

21
ответ дан Yukulélé 21 August 2018 в 16:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: