Konfiguruję globalne przestrzenie nazw dla moich obiektów, ustawiając jawnie właściwość na window
.
window.MyNamespace = window.MyNamespace || {};
TypeScript podkreśla MyNamespace
i narzeka, że:
Właściwość „MyNamespace” nie istnieje dla wartości typu „window” any ”
Mogę sprawić, aby kod działał, deklarując MyNamespace
jako zmienną otoczenia i usuwając window
jawność, ale nie chcę tego robić.
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
Jak mogę window
tam pozostać i sprawić, że TypeScript będzie szczęśliwy?
Na marginesie uważam za szczególnie zabawne, że narzeka TypeScript, ponieważ mówi mi, że window
jest to typ, any
który zdecydowanie może zawierać wszystko.
typescript
joshuapoehls
źródło
źródło
Odpowiedzi:
Właśnie znalazłem odpowiedź na to pytanie w odpowiedzi na inne pytanie StackOverflow .
Zasadniczo musisz rozszerzyć istniejący
window
interfejs, aby poinformować go o swojej nowej właściwości.źródło
.d.ts
pliku. Nie działa, gdy jest używany w.ts
pliku, który używa samego importu i eksportu. Zobacz tę odpowiedź .declare global { interface Window { ... } }
prace z maszynopis 2.5.2, nie ma potrzeby do.d.ts
pliku, jak wspomniano powyżejerror TS1234: An ambient module declaration is only allowed at the top level in a file.
kiedy umieściłem go na górze pliku, naprawił ten błąd, więc być może będziesz musiał to zrobić.Aby zachować dynamikę, po prostu użyj:
źródło
as
zamiast<>
. Zobacz odpowiedź @ david-boyd poniżej .this
-return (<any> this)['something in scope']
/* tslint:disable */
STANU TYPU ^ 3.4.3 TO ROZWIĄZANIE NIE DZIAŁA DŁUGO
Lub...
możesz po prostu wpisać:
i nie pojawi się błąd kompilacji i działa tak samo jak pisanie
window.MyNamespace
źródło
window['MyNamespace']()
(wystarczy dodać nawiasyUżywasz TSX? Żadna z pozostałych odpowiedzi nie działała dla mnie.
Oto co zrobiłem:
źródło
(<any> window).MyNamespace
rzeczywistości<any>
interpretowany jest jako JSX, a nie rzut typu.Zaakceptowałem odpowiedź, z której korzystałem, ale z TypeScript 0.9. * To już nie działa. Nowa definicja
Window
interfejsu wydaje się całkowicie zastępować wbudowaną definicję, zamiast ją rozszerzać.Zamiast tego zdecydowałem się to zrobić:
AKTUALIZACJA: Z TypeScript 0.9.5 zaakceptowana odpowiedź znów działa.
źródło
export default class MyClass{ foo(){ ... } ... }
interface MyWindow extends Window{ mc: MyClass }
declare var window: MyWindow
window.mc = new MyClass()
wtedy możesz wywołać foo () np. Z konsoli Chrome Dev Tools, np.mc.foo()
declare var...
każdy potrzebny plik.Window
prostego faktu, że nie jest to okno waniliowe. Samo obejście sprawdzania typu lub próba oszukiwania TS również nie jest na to sposobem.Globalne są „złe” :), myślę, że najlepszym sposobem na przeniesienie jest:
Najpierw eksportujesz interfejs: (np .: ./custom.window.ts)
Drugi import
Trzecie rzutowanie globalnego okna var z CustomWindow
W ten sposób nie masz czerwonej linii w innym IDE, jeśli używasz z istniejącymi atrybutami obiektu okna, więc na koniec spróbuj:
Testowane z Typescript 2.4.x i nowszymi!
źródło
Jeśli chcesz rozszerzyć
window
obiekt o niestandardowy typ, który wymaga użyciaimport
, możesz użyć następującej metody:Window.d.ts
Zobacz „Globalne rozszerzanie” w sekcji „Łączenie deklaracji” w podręczniku: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
źródło
Dla osób korzystających z Angular CLI jest to proste:
src / polyfills.ts
my-custom-utils.ts
Jeśli używasz IntelliJ, musisz także zmienić następujące ustawienie w IDE przed pobraniem nowych wielopełniaczy:
źródło
declare global
jest sztuczką, a ta odpowiedź nie jest specjalnie specyficzna dla Angular CLI ...Nie muszę tego robić zbyt często, jedynym przypadkiem było użycie Redux Devtools z oprogramowaniem pośrednim.
Po prostu zrobiłem:
Lub możesz zrobić:
let myWindow = window as any;
i wtedy
myWindow.myProp = 'my value';
źródło
Większość innych odpowiedzi nie jest idealna.
Podobny problem napotykam także dziś rano. Próbowałem tak wielu „rozwiązań” na SO, ale żadne z nich nie generuje absolutnie żadnego błędu typu i włącza wyzwalanie skoków typów w IDE (burza internetowa lub vscode).
Wreszcie stąd
, Znajduję rozsądne rozwiązanie, aby dołączyć typy dla zmiennej globalnej, która działa zarówno jako interfejs / klasa, jak i przestrzeń nazw .
Przykład jest poniżej:
Teraz powyższy kod łączy typy przestrzeni nazw
MyNamespace
i interfejsuMyNamespace
w zmienną globalnąmyNamespace
(właściwość okna).źródło
Po znalezieniu odpowiedzi uważam, że ta strona może być pomocna. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Nie jestem pewien historii łączenia deklaracji, ale wyjaśnia, dlaczego poniższe działania mogą działać.
źródło
Oto jak to zrobić, jeśli używasz Menedżera definicji TypeScript !
Utwórz
typings/custom/window.d.ts
:Zainstaluj niestandardowe pisanie:
Gotowe, użyj go ! Maszynopis nie będzie już narzekał:
źródło
typings
stało się przestarzałe z Typescript 2.0 (połowa 2016 r.) I zostało zarchiwizowane przez właściciela.Maszynopis nie wykonuje kontroli typu we właściwościach łańcucha.
Najlepiej byłoby uniknąć scenariusza zmiennej globalnej. Czasami używam go do debugowania obiektu w konsoli przeglądarki.
źródło
Utwórz plik o nazwie
global.d.ts
np./src/@types/global.d.ts
Następnie zdefiniuj interfejs, taki jak:ref: https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-d-ts.html
źródło
Jeśli używasz Typescript 3.x, możesz pominąć
declare global
część w innych odpowiedziach, a zamiast tego użyć:Działa to ze mną podczas korzystania z Typescript 3.3, WebPack i TSLint.
źródło
^3.4.3
. Ta odpowiedź działała na mnie stackoverflow.com/a/42841166/1114926Dla odniesienia (to jest poprawna odpowiedź):
Wewnątrz
.d.ts
pliku definicjiJeśli pracujesz w przeglądarce, dodajesz członków do kontekstu okna przeglądarki, ponownie otwierając interfejs Windows:
Ten sam pomysł dla NodeJS:
Teraz zadeklarujesz zmienną główną (która faktycznie będzie działać w oknie lub globalnie)
Następnie w zwykłym
.ts
pliku, ale zaimportowanym jako efekt uboczny, faktycznie go implementujesz:I w końcu użyj go gdzie indziej w bazie kodu, albo:
źródło
Utwórz niestandardowy interfejs rozszerza okno i dodaj niestandardową właściwość jako opcjonalną.
Następnie pozwól customWindow, które korzystają z niestandardowego interfejsu, ale wyceniane w oryginalnym oknie.
Działa z [email protected].
źródło
Dla tych, którzy chcą ustawić obliczoną lub dynamiczną właściwość
window
obiektu, przekonasz się, że tadeclare global
metoda nie jest możliwa . Wyjaśnienie dla tego przypadku użyciaMożesz spróbować zrobić coś takiego
Powyższe spowoduje błąd. Wynika to z faktu, że w Typescript interfejsy nie działają dobrze z obliczonymi właściwościami i generują błąd podobny do tego
Aby obejść ten problem, można przejść z sugerować odlewania
window
do<any>
tak można zrobićźródło
Za pomocą create-React-app v3.3 znalazłem najłatwiejszy sposób na osiągnięcie tego celu, aby rozszerzyć
Window
typ w generowanym automatyczniereact-app-env.d.ts
:źródło
Najpierw musisz zadeklarować obiekt okna w bieżącym zakresie.
Ponieważ maszynopis chciałby poznać typ obiektu.
Ponieważ obiekt okna jest zdefiniowany gdzie indziej, nie można go przedefiniować.
Ale możesz to zadeklarować w następujący sposób:
To nie przedefiniuje obiektu okna lub nie utworzy innej zmiennej o nazwie
window
.Oznacza to, że okno jest zdefiniowane gdzie indziej i po prostu odwołujesz się do niego w bieżącym zakresie.
Następnie możesz odwołać się do obiektu MyNamespace po prostu przez: -
Lub możesz ustawić nową właściwość na
window
obiekcie po prostu przez: -A teraz maszynopis nie będzie narzekał.
źródło
window
jest zdefiniowany?Chciałem użyć tego dzisiaj w bibliotece Angular (6) i zajęło mi to trochę czasu, aby to zadziałało zgodnie z oczekiwaniami.
Aby moja biblioteka mogła korzystać z deklaracji, musiałem użyć
d.ts
rozszerzenia dla pliku deklarującego nowe właściwości obiektu globalnego.Ostatecznie plik skończył się tak:
/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts
Po utworzeniu nie zapomnij go ujawnić w swoim
public_api.ts
.To mi zrobiło. Mam nadzieję że to pomoże.
źródło