Jak jawnie ustawić nowy obiekt na `window` na maszynie?

głosy
247

I konfiguracji globalnej przestrzeni nazw dla moich przedmiotów jawnie ustawienie na własność window.

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

Maszynopis podkreśla MyNamespacei skarży się, że:

Nieruchomość „MyNamespace” nie istnieje na wartości typu „okno” każdy”

Mogę uczynić pracę kodu deklarując MyNamespacejako zmienna otoczenia i upuszczenie windowjednoznaczność, ale nie chcę tego robić.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Jak mogę utrzymać windowtam i zrobić maszynopis szczęśliwy?

Na marginesie uważam, że to szczególnie zabawne, że maszynopis narzeka ponieważ mówi mi, że windowjest typu any, który przez zdecydowanie może zawierać niczego.

Utwórz 03/10/2012 o 14:01
źródło użytkownik
W innych językach...                            


19 odpowiedzi

głosy
253

Aby utrzymać dynamiczny, wystarczy użyć:

(<any>window).MyNamespace
Odpowiedział 09/06/2015 o 19:18
źródło użytkownik

głosy
235

Wystarczy znaleźć odpowiedź na to w odpowiedzi na pytanie innego StackOverflow .

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

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

Zasadniczo trzeba rozszerzyć istniejący windowinterfejs, aby poinformować go o swoim nowym domu.

Odpowiedział 03/10/2012 o 14:46
źródło użytkownik

głosy
127

Lub...

można po prostu wpisać:

window['MyNamespace']

i przyzwyczajenie się błąd kompilacji i działa tak samo jak pisanie window.MyNamespace

Odpowiedział 20/11/2012 o 20:36
źródło użytkownik

głosy
84

Korzystanie TSX? Żaden z pozostałych odpowiedzi pracowali dla mnie.

Oto co zrobiłem:

(window as any).MyNamespace
Odpowiedział 15/08/2016 o 23:25
źródło użytkownik

głosy
46

Przyjęty odpowiedzią jest to, co ja używałem, ale z maszynopis 0.9. * To już nie działa. Nowa definicja Windowinterfejsu wydaje się całkowicie zastąpić wbudowany definicję, zamiast zwiększając ją.

Brałem aby robić to w zamian:

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

declare var window: MyWindow;

UPDATE: Z maszynopis 0.9.5 przyjętą odpowiedź działa ponownie.

Odpowiedział 27/08/2013 o 22:22
źródło użytkownik

głosy
29

Jeśli trzeba rozszerzyć windowprzedmiot z niestandardowego typu, który wymaga użycia importmożna użyć w następujący sposób:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Patrz „Globalny Powiększanie” w „Deklaracji” Łączenie części podręcznika: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

Odpowiedział 23/10/2016 o 15:24
źródło użytkownik

głosy
19

Globalny są „złe” :), myślę, że najlepszym sposobem, aby mieć również możliwość przenoszenia wynosi:

Najpierw wyeksportować interfejsu (np ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Drugi importowania

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

Trzeci cast globalny okno var z CustomWindow

declare let window: CustomWindow;

W ten sposób nie trzeba też czerwoną linię w innym IDE jeśli korzystania z istniejących atrybutów obiektu window, więc przy próbie końcowego:

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

Testowane z maszynopis 2.4.x

Odpowiedział 27/07/2017 o 13:28
źródło użytkownik

głosy
8

Oto jak to zrobić, jeśli używasz maszynopis Definicja Menedżer !

npm install typings --global

Tworzenie typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Zainstalować niestandardowy wpisując:

typings install file:typings/custom/window.d.ts --save --global

Sporządzono, użyj go ! Maszynopis już nie będzie narzekać:

window.MyNamespace = window.MyNamespace || {};
Odpowiedział 19/11/2016 o 21:31
źródło użytkownik

głosy
7

Nie muszę tego robić zbyt często, to jedyny przypadek miałem było podczas korzystania Redux DevTools z middleware.

Po prostu zrobiłem:

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

Albo można zrobić:

let myWindow = window as any;

i wtedy myWindow.myProp = 'my value';

Odpowiedział 06/06/2018 o 13:13
źródło użytkownik

głosy
5

Większość z pozostałych odpowiedzi nie są doskonałe.

  • Niektóre z nich po prostu stłumić wnioskowanie typu dla sklepu.
  • Niektóre z innymi dba tylko o zmiennej globalnej jako nazw, ale nie jako interfejsu / klasy

Ja też spotkać się z podobnym problemem to rano. Próbowałem tak wiele „rozwiązań” na SO, ale żaden z nich nie wytwarzają typu błędu absolutnie i umożliwiają wyzwalanie typu skoki w IDE (webstorm lub vscode).

Wreszcie, stąd

https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

Uważam, że rozsądne rozwiązanie do przywiązują typowania dla zmiennej globalnej, która działa jako interfejsu / klasy i nazw obu .

Przykład poniżej:

// typings.d.ts
declare interface Window {
    myNamespace?: MyNamespace & typeof MyNamespace
}

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Teraz powyższy kod łączy typowania z nazw MyNamespacei interfejs MyNamespacedo zmiennej globalnej myNamespace(własność okna).

Odpowiedział 19/05/2017 o 03:26
źródło użytkownik

głosy
5

Jeśli używasz kątowa CLI to naprawdę proste (testowane na CLI RC.0):

src / polyfills.ts

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

my-custom-utils.ts

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

Używam IntelliJ, więc ja też potrzebne, aby zmienić następujące ustawienia w IDE przed moi nowi polyfills podniósł:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
Odpowiedział 21/03/2017 o 13:38
źródło użytkownik

głosy
2

Dla tych, którzy chcą ustawić komputerowej lub dynamiczny obiekt w windowobiekcie, przekonasz się, że nie jest możliwe z declare globalmetody. W celu wyjaśnienia tego przypadku użycia

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

Można próbować zrobić coś takiego

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

Powyższe będzie błędu, mimo. To dlatego, że w maszynopisie, interfejsy nie gra dobrze z obliczonymi właściwościami i wygeneruje błąd podobny

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

Aby obejść ten problem, można przejść z sugerować odlewania windowdo <any>tak można zrobić

(window as any)[DynamicObject.key]
Odpowiedział 13/02/2019 o 00:15
źródło użytkownik

głosy
2

Zrób niestandardowy interfejs rozszerza okno i dodać właściwość niestandardową jako opcjonalne.

Następnie, niech customWindow które wykorzystują interfejs niestandardowy, ale ceniony z oryginalnego okna.

To pracował z typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
Odpowiedział 12/11/2018 o 07:29
źródło użytkownik

głosy
2

Chciałem użyć tego w kątowym (6) biblioteki dzisiaj i zajęło mi trochę czasu, aby dostać to, aby działać zgodnie z oczekiwaniami.

Aby mojej biblioteki do wykorzystania deklaracji musiałem użyć d.tsprzedłużeniu do pliku, który stwierdzi, że nowe właściwości obiektu globalnego.

Więc w końcu, plik skończyło się coś takiego:

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

Po utworzeniu, nie zapomnij, aby wystawiać go w public_api.ts.

Że zrobił to dla mnie. Mam nadzieję że to pomoże.

Odpowiedział 01/08/2018 o 11:29
źródło użytkownik

głosy
2

Dla odniesienia (to jest poprawna odpowiedź):

Wewnątrz .d.tspliku definicji

type MyGlobalFunctionType = (name: string) => void

Jeśli pracujesz w przeglądarce, dodasz członków do kontekstu okna przeglądarki przez ponowne otwarcie okna interfejsu:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Sam pomysł na NodeJS:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}

Teraz można zadeklarować zmienną głównego (które będą faktycznie żyją na oknie lub globalne)

declare const myGlobalFunction: MyGlobalFunctionType;

Następnie w zwykłym .tspliku, ale importowane jako efekt uboczny, to rzeczywiście wdrożyć go:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};

I wreszcie używać go w innym miejscu w kodzie, albo z:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");
Odpowiedział 20/04/2017 o 15:50
źródło użytkownik

głosy
1

Jeśli używasz maszynopis 3.x, możesz pominąć declare globaludział w innych odpowiedzi i zamiast po prostu użyć:

interface Window {
  someValue: string
  another: boolean
}

Ten pracował ze mną podczas korzystania maszynopis 3.3 WebPACK i TSLint.

Odpowiedział 12/02/2019 o 21:50
źródło użytkownik

głosy
0

Typescript nie wykonuje typecheck na właściwości ciągów.

window["newProperty"] = customObj;

Idealnie, zmienna globalna scenariusz powinien unikać. Używam go czasami do debugowania obiektu w konsoli przeglądarki.

Odpowiedział 18/06/2019 o 22:01
źródło użytkownik

głosy
0

Najpierw trzeba zadeklarować obiekt okna w bieżącym zakresie.
Ponieważ maszynopis chcieliby wiedzieć typ obiektu.
Ponieważ okno obiekt jest zdefiniowany gdzie indziej nie można zdefiniować ją.
Ale można zadeklarować je w następujący sposób: -

declare var window: any;

To nie będzie przedefiniować obiekt okna albo nie stworzy kolejną zmienną o nazwie window.
Oznacza to okno jest zdefiniowana gdzieś indziej i dopiero przedstawieniu go w dotychczasowym zakresie.

Następnie można odnieść do obiektu MyNamespace po prostu: -

window.MyNamespace

A teraz maszynopis nie będą narzekać.

Odpowiedział 01/06/2019 o 01:41
źródło użytkownik

głosy
-1

Po znalezieniu odpowiedzi wokół, myślę, że ta strona może być pomocne. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Nie wiesz o historii deklaracji przejmowanego, ale to wyjaśnia dlaczego następujący mógł pracować.

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

window.MyNamespace = window.MyNamespace || {};
Odpowiedział 16/03/2017 o 17:38
źródło użytkownik

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