declare în TypeScript

Module și declarații TypeScript 1.0

Anunță compilatorul că o variabilă, funcție sau modul există deja la rulare, fără să genereze cod pentru ea.

Sintaxă
declare const VERSIUNE: string;
declare function f(x: number): string;
declare global { interface Window { ... } }
declare module "pachet" { ... }

Ce face declare

declare descrie ceva care există la rulare, dar care nu este scris în codul TypeScript: o variabilă globală pusă de un script din pagină, o funcție dintr-o bibliotecă JavaScript, o constantă înlocuită de bundler. Declarația are doar tip, fără valoare sau corp, și nu produce niciun rând de JavaScript.

Forme frecvente: declare const/declare function/declare class pentru valori globale; declare global { ... }, într-un modul, pentru a adăuga ceva în spațiul global (de exemplu o proprietate pe Window sau o variabilă pe globalThis); declare module "nume" { ... } pentru a descrie sau completa tipurile unui pachet. Declarațiile stau de obicei în fișiere .d.ts.

Atenție: declare este o promisiune. Dacă valoarea nu există de fapt, codul compilează, dar la rulare primești ReferenceError. Pe câmpurile claselor, declare camp: Tip declară tipul unui câmp fără să-l inițializeze.

Exemple

Exemplul 1: Variabilă globală adăugată cu declare global

var în declare global adaugă proprietatea pe globalThis. Valoarea este pusă la rulare, ca de un script de configurare.

declare global {
    var configurare: { oras: string; limba: string } | undefined;
}

globalThis.configurare = { oras: "Iași", limba: "ro" };

function salut(): string {
    const c = globalThis.configurare;
    return c ? `Bun venit în ${c.oras} (${c.limba})` : "Fără configurare";
}

console.log(salut());

Rezultat

Bun venit în Iași (ro)

Exemplul 2: declare nu creează valoarea

Compilarea trece, dar constanta nu există la rulare. Eroarea este prinsă ca să vezi mesajul.

declare const VERSIUNE: string;

try {
    console.log("Versiunea:", VERSIUNE);
} catch (e) {
    console.log((e as Error).name + ":", (e as Error).message);
}

Rezultat

ReferenceError: VERSIUNE is not defined

Exemplul 3: Completarea unei interfețe globale

Array este o interfață globală, deci declare global îi poate adăuga o metodă. Implementarea se pune pe Array.prototype.

declare global {
    interface Array<T> {
        ultimul(): T | undefined;
    }
}

Array.prototype.ultimul = function <T>(this: T[]): T | undefined {
    return this[this.length - 1];
};

console.log(["Iași", "Cluj", "Brașov"].ultimul(), [].ultimul());

Rezultat

Brașov undefined

Greșeli frecvente

  • Scrii declare const x = 5. O declarație nu poate avea valoare; tsc dă Initializers are not allowed in ambient contexts.
  • Folosești declare global într-un fișier care nu este modul. Este permis doar în module; într-un script, declarațiile sunt deja globale.
  • Modifici prototipurile obiectelor predefinite în cod de bibliotecă. Poate intra în conflict cu alte biblioteci sau cu metode viitoare din JavaScript.

Comenzi înrudite

  • fișiere .d.ts: Fișiere care conțin doar tipuri: descriu codul JavaScript ca să poată fi folosit din TypeScript cu verificare.
  • namespace: Grupează cod sub un nume comun; este forma veche de organizare, înlocuită azi de module ES.
  • tipuri pentru DOM: Tipurile pentru pagina web (document, elemente, evenimente) vin din biblioteca dom a TypeScript.
  • interface: Descrie forma unui obiect: ce proprietăți are, de ce tip sunt și ce metode are.