Cum setezi în mod explicit o proprietate nouă pe `window` în TypeScript?
Am configurat spații de nume globale pentru obiectele mele prin setarea explicită a unei proprietăți pe window.
window.MyNamespace = window.MyNamespace || {};
TypeScript subliniază MyNamespace și se plânge că:
Proprietatea 'MyNamespace' nu există pe valoarea de tip 'window' any
Pot face ca codul să funcționeze declarând MyNamespace ca o variabilă ambientală și eliminând explicitarea window, dar nu vreau să fac asta.
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
Cum pot păstra window acolo și să fac TypeScript fericit?
Ca o observație secundară, mi se pare în mod special amuzant că TypeScript se plânge deoarece îmi spune că window este de tip any, care cu siguranță poate conține orice.
Răspuns #1
Tocmai am găsit răspunsul la asta într-un alt răspuns al unei întrebări de pe Stack Overflow.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
Practic, trebuie să extinzi interfața existentă window pentru a-i spune despre noua ta proprietate.
Răspunsul #2
Pentru a-l menține dinamic, folosește pur și simplu:
(<any>window).MyNamespace
Rețineți că acest lucru s-ar putea să nu funcționeze cu TSX deoarece compilatorul ar putea crede că <any> este un element TSX. Consultați acest răspuns pentru afirmarea tipului care este compatibilă cu TSX.
Răspunsul #3
Folosești Svelte sau TSX? Niciuna dintre celelalte răspunsuri nu funcționa pentru mine.
Iată ce am făcut:
(window as any).MyNamespace
Răspunsul #4
Începând cu TypeScript ^3.4.3, această soluție nu mai funcționează :
Sau...
poți pur și simplu să tastezi:
window['MyNamespace']
Și nu vei primi o eroare de compilare și funcționează la fel ca atunci când tastezi window.MyNamespace.
Răspuns #5
Variabilele globale sunt „rele” :) Cred că cea mai bună metodă de a avea și portabilitatea este:
Mai întâi exporți interfața: (de exemplu, ./custom.window.ts)
export interface CustomWindow extends Window {
customAttribute: any;
}
În al doilea rând, importați
import {CustomWindow} from './custom.window.ts';
În al treilea rând, transformă variabila globală window în CustomWindow:
declare let window: CustomWindow;
În acest fel nu vei avea nici o linie roșie într-un alt IDE dacă îl folosești cu atributele existente ale obiectului window, deci la final încearcă:
window.customAttribute = 'works';
window.location.href = '/works';
Testat cu TypeScript 2.4.x și cele mai noi!
Răspunsul #6
Este simplu:
Fișier src/polyfills.ts
declare global {
interface Window {
myCustomFn: () => void;
}
}
Fișier my-custom-utils.ts
window.myCustomFn = function () {
...
};
Dacă folosești IntelliJ IDEA, de asemenea trebuia să modifici următoarea setare din IDE înainte ca noile tale polyfill-uri să fie recunoscute:
> File
> Settings
> Languages & Frameworks
> TypeScript
> check 'Use TypeScript Service'.
Răspunsul #7
Răspunsul acceptat este ceea ce obișnuiam să folosesc, dar cu TypeScript 0.9.* nu mai funcționează. Noua definiție a interfeței Window pare să înlocuiască complet definiția încorporată, în loc să o completeze.
Am început să fac asta în schimb:
interface MyWindow extends Window {
myFunction(): void;
}
declare var window: MyWindow;
ACTUALIZARE: Cu TypeScript 0.9.5, răspunsul acceptat funcționează din nou.
Răspunsul #8
Dacă trebuie să extindeți obiectul window cu un tip personalizat care necesită utilizarea import, puteți folosi următoarea metodă:
window.d.ts
import MyInterface from './MyInterface';
declare global {
interface Window {
propName: MyInterface
}
}
Consultați Secțiunea „Fuziunea Declarațiilor” din Manual pentru Augmentarea Globală.
Răspunsul #9
Creează un fișier numit global.d.ts, de exemplu, /src/@types/global.d.ts, și apoi definește o interfață astfel:
interface Window {
myLib: any
}
Referință: Global .d.ts
Răspuns #10
Majoritatea celorlalte răspunsuri nu sunt perfecte.
- Unii dintre ei doar suprimă inferența tipului pentru show.
- Unii dintre ceilalți se preocupă doar de variabilele globale ca spații de nume, dar nu și ca interfețe/clase
De asemenea, m-am confruntat cu o problemă similară în această dimineață. Am încercat atât de multe „soluții” pe Stack Overflow, dar niciuna dintre ele nu a produs absolut nicio eroare de tip și nu a permis declanșarea săriturii între tipuri în IDE (WebStorm sau Visual Studio Code).
În cele din urmă, din Permite definițiile modulului să fie declarate ca variabile globale #3180
Am găsit o soluție rezonabilă pentru atașarea tipurilor pentru o variabilă globală care funcționează atât ca interfață/clasă, cât și ca namespace.
Exemplul este mai jos:
// typings.d.ts
declare interface Window {
myNamespace?: MyNamespace & typeof MyNamespace
}
declare interface MyNamespace {
somemethod?()
}
declare namespace MyNamespace {
// ...
}
Codul de mai sus fuzionează tipurile din namespace-ul MyNamespace și interfața MyNamespace în variabila globală myNamespace (proprietatea window).
Răspunsul #11
Nu am nevoie să fac asta foarte des. Singurul caz pe care l-am avut a fost când foloseam Redux DevTools cu middleware.
Pur și simplu am făcut:
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
Sau ai putea face:
let myWindow = window as any;Și apoi myWindow.myProp='my value';
Răspuns #12
După ce am găsit răspunsuri pe ici, pe colo, cred că această pagină ar putea fi de ajutor:
Creștere globală
Nu sunt sigur cu privire la istoria fuziunii declarațiilor, dar explică de ce următorul lucru ar putea funcționa.
declare global {
interface Window { MyNamespace: any; }
}
window.MyNamespace = window.MyNamespace || {};
Răspunsul #13
Începând cu versiunea 3.4, TypeScript a suportat globalThis. Vezi Verificarea tipurilor pentru globalThis.
De la linkul de mai sus:
// in a global file:
var abc = 100;
// Refers to 'abc' from above.
globalThis.abc = 200;
window.abc = 300; // window object can also be used.
Teren de joacă
Un fișier „global” este un fișier care nu are niciun fel de declarații import/export. Așadar, declarația var abc; poate fi scrisă în .d.ts.
Răspuns #14
Dacă folosiți TypeScript 3.x, este posibil să puteți omite partea declare global din celelalte răspunsuri și să folosiți în schimb doar:
interface Window {
someValue: string
another: boolean
}
Acest lucru a funcționat pentru mine atunci când foloseam TypeScript 3.3, Webpack și TSLint.
Răspuns #15
Folosind create-react-app v3.3, am descoperit că cea mai simplă modalitate de a realiza acest lucru a fost să extind tipul Window în fișierul react-app-env.d.ts generat automat:
interface Window {
MyNamespace: any;
}
Răspuns #16
TypeScript nu efectuează verificarea tipurilor pentru proprietățile de tip șir.
window["newProperty"] = customObj;
Ideal, scenariul cu variabile globale ar trebui evitat. Îl folosesc uneori pentru a depana un obiect în consola browserului.
Răspunsul #17
Folosind
window["MyNamespace"] = window["MyNamespace"] || {};
ar trebui să fie în regulă așa cum este folosind o proprietate de tip șir, dar dacă vrei cu adevărat să ai o fereastră separată și să-ți organizezi codul, poți extinde obiectul fereastră:
interface MyNamespacedWindow extends Window {
MyNamespace: object;
}
declare var window: MyNamespacedWindow;
Răspunsul #18
// In typings.d.ts(is Global)
export declare global {
interface Window {
__PUBLIC__: string;
}
}
Răspunsul #19
Iată cum să faci asta, dacă folosești TypeScript Definition Manager!
npm install typings --global
Creează typings/custom/window.d.ts:
interface Window {
MyNamespace: any;
}
declare var window: Window;
Instalează tastarea ta personalizată:
typings install file:typings/custom/window.d.ts --save --global
Gata! Folosește-l! TypeScript nu se va mai plânge:
window.MyNamespace = window.MyNamespace || {};
Răspuns #20
[2022]: Trebuie să extindem obiectul "window" în proiectul nostru React sau Nextjs. Putem folosi următorul pas pentru a rezolva această problemă.
Creează un folder în interiorul folderului src și numește-l types.
Creează un fișier în interiorul folderului types numit index.d.ts
scrie acest cod în fișierul index.d.ts.
export {}; declare global { interface Window { NameSpace: any; } } window.NameSpace= window.NameSpace|| {};
Acum încă o ultimă schimbare.
Schimbați fișierul "tsConfig.json" pentru a moșteni atât tipul modulului node, cât și tipurile noastre.
{
"compilerOptions": {
...
"typeRoots": [
"./node_modules/@types",
"./src/types"
],
....
}
Răspuns #21
Mai întâi trebuie să declari obiectul window în domeniul curent. Pentru că TypeScript ar dori să știe tipul obiectului. Deoarece obiectul window este definit în altă parte, nu îl poți redefini.
Dar îl poți declara după cum urmează:
declare var window: any;
Acest lucru nu va redefini obiectul window și nici nu va crea o altă variabilă cu numele window. Aceasta înseamnă că window este definit în altă parte și tu doar îl referențiezi în domeniul curent.
Atunci poți să te referi la obiectul tău MyNamespace pur și simplu prin:
window.MyNamespace
Sau poți seta noua proprietate pe obiectul window pur și simplu prin:
window.MyNamespace = MyObject
Și acum TypeScript nu se va plânge.
Răspunsul #22
Răspuns complet și scurt
1- Adaugă proprietatea typeRoots în tsconfig.json:
{
"compilerOptions": {
...
"typeRoots": ["src/@types", "node_modules/@types"]
...
}
}
2- Extindeți tipul Window
// file: src/@types/global.d.ts
declare global {
interface Window { customProperty: <type>; }
}
Răspunsul #23
Două metode:
#1: creează un fișier global.d.ts, acest nume de fișier poate fi ales aleatoriu, dar trebuie să fie inclus în directorul verificat de TypeScript, apoi poți folosi namespace-ul declare global pentru a defini proprietăți noi pe Window:
declare global {
interface Window {
myCustomFn: () => void;
}
}
// At least one export statement
export {};
#2: creează un fișier global.d.ts, acest nume de fișier poate fi aleator, dar trebuie inclus în directorul verificat de TypeScript, și nu poți folosi niciun import sau export în acest fișier. apoi poți folosi pur și simplu interface pentru a defini noi proprietăți pe Window:
//~ just need this
interface Window {
myProperty: string;
}



