Как вы явно установить новое свойство на `window` в машинописном?

голоса
247

Настройка I глобальные пространства имен для моих объектов, явно устанавливая свойство на window.

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

Машинопись подчеркивает MyNamespaceи жалуется , что:

Свойство «MyNamespace» не существует на значение типа «окна» любой»

Я могу сделать код работы, объявляя в MyNamespaceкачестве переменной окружающей среды и опуская windowэксплицитность , но я не хочу , чтобы сделать это.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Как я могу держать windowтам и сделать машинопись счастливым?

Как примечание стороны я нахожу это особенно смешно , что машинопись жалуется , так как он говорит мне , что windowэто типа , anyкоторый по определенно может содержать что - нибудь.

Задан 03/10/2012 в 14:01
источник пользователем
На других языках...                            


19 ответов

голоса
253

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

(<any>window).MyNamespace
Ответил 09/06/2015 в 19:18
источник пользователем

голоса
235

Просто найти ответ на этот вопрос в ответ другой StackOverflow вопрос , в .

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

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

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

Ответил 03/10/2012 в 14:46
источник пользователем

голоса
127

Или...

Вы можете просто ввести:

window['MyNamespace']

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

Ответил 20/11/2012 в 20:36
источник пользователем

голоса
84

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

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

(window as any).MyNamespace
Ответил 15/08/2016 в 23:25
источник пользователем

голоса
46

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

Я взял делать вместо этого:

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

declare var window: MyWindow;

UPDATE: С машинописью 0.9.5 принятого ответ снова работает.

Ответил 27/08/2013 в 22:22
источник пользователем

голоса
29

Если вам необходимо расширить 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

Ответил 23/10/2016 в 15:24
источник пользователем

голоса
19

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

Прежде чем экспортировать интерфейс: (например: ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Во-вторых импорт

import {CustomWindow} from './custom.window.ts';

Третье отливать глобальное окно уага с CustomWindow

declare let window: CustomWindow;

Таким образом, вы не должны также красная линия в различном IDE, если вы используете с существующими атрибутами объекта окна, так что в конце концов попытки:

window.customAttribute = 'works';
window.location.href = '/works';

Испытано с машинопись 2.4.x

Ответил 27/07/2017 в 13:28
источник пользователем

голоса
8

Вот как это сделать, если вы используете Машинопись Определение диспетчера !

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

Готово, используйте его ! Машинопись не будут жаловаться больше:

window.MyNamespace = window.MyNamespace || {};
Ответил 19/11/2016 в 21:31
источник пользователем

голоса
7

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

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

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

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

let myWindow = window as any;

а потом myWindow.myProp = 'my value';

Ответил 06/06/2018 в 13:13
источник пользователем

голоса
5

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

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

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

Ответил 19/05/2017 в 03:26
источник пользователем

голоса
5

Если вы используете Угловое CLI это действительно просто (проверено на CLI rc.0):

SRC / polyfills.ts

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

мой-таможенно-utils.ts

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

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

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
Ответил 21/03/2017 в 13:38
источник пользователем

голоса
2

Для тех , кто хочет установить вычисленное или динамическое свойство на windowобъекте, вы обнаружите , что не представляется возможным с declare globalметодом. Для того, чтобы прояснить для этого случая использования

window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature

Вы могли бы попытаться сделать что-то вроде этого

declare global {
  interface Window {
    [DyanmicObject.key]: string; // error RIP
  }
}

Выше будет ошибка, хотя. Это происходит потому, что в машинописном, интерфейсы не очень хорошо с вычисленными свойствами и выдаст сообщение об ошибке, как

A computed property name in an interface must directly refer to a built-in symbol

Чтобы обойти эту проблему , вы можете пойти с внушал кастинг windowна <any>так что вы можете сделать

(window as any)[DynamicObject.key]
Ответил 13/02/2019 в 00:15
источник пользователем

голоса
2

Сделать заказ интерфейс расширяет окно и добавить пользовательское свойство, как опция.

Тогда, пусть customWindow, которые используют пользовательский интерфейс, но с оцениваемым исходным окном.

Он работал с typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
Ответил 12/11/2018 в 07:29
источник пользователем

голоса
2

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

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

Таким образом, в конце концов, файл в конечном итоге с чем-то вроде:

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

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

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

Ответил 01/08/2018 в 11:29
источник пользователем

голоса
2

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

Внутри .d.tsфайла определения

type MyGlobalFunctionType = (name: string) => void

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

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");
Ответил 20/04/2017 в 15:50
источник пользователем

голоса
1

Если вы используете машинопись 3.x, вы можете быть в состоянии опустить declare globalчасть в других ответах, а просто использовать:

interface Window {
  someValue: string
  another: boolean
}

Это работало со мной при использовании машинописи 3.3, WebPack и TSLint.

Ответил 12/02/2019 в 21:50
источник пользователем

голоса
0

Typscript не выполняет typecheck строковых свойств.

window["newProperty"] = customObj;

В идеале, глобальная переменная сценария следует избегать. Я использую его иногда отладить объект в консоли браузера.

Ответил 18/06/2019 в 22:01
источник пользователем

голоса
0

Прежде всего , необходимо объявить объект окна в текущей области.
Потому что машинопись хотела бы знать тип объекта.
Так как объект окна определяется где - то еще , вы не можете переопределить его.
Но вы можете объявить его следующим образом : -

declare var window: any;

Это не будет переопределить объект окна или он не будет создавать еще одну переменную с именем window.
Это означает , что окно определенно где - то еще , и вы просто ссылаться на него в текущей области.

После этого вы можете обратиться к объекту MyNamespace просто: -

window.MyNamespace

А теперь машинопись не будет жаловаться.

Ответил 01/06/2019 в 01:41
источник пользователем

голоса
-1

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

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

window.MyNamespace = window.MyNamespace || {};
Ответил 16/03/2017 в 17:38
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more