namespace în TypeScript

Module și declarații TypeScript 1.5

Grupează cod sub un nume comun; este forma veche de organizare, înlocuită azi de module ES.

Sintaxă
namespace Nume {
    export const x = 1;
    export function f() { ... }
}
Nume.f();

Ce face namespace

Un namespace (numit înainte internal module) grupează funcții, clase și tipuri sub un nume: Geometrie.arie(...). Doar ce este marcat export în interior se vede din afară. La compilare, un namespace devine un obiect JavaScript creat de o funcție care se apelează imediat.

A apărut înainte de modulele ES. Azi, în cod nou, folosește module: fiecare fișier este propriul spațiu de nume, iar uneltele moderne (bundlere, tree-shaking) lucrează cu ele. Opțiunea erasableSyntaxOnly interzice namespace-urile care conțin cod, pentru că nu pot fi șterse simplu ca tipurile.

Namespace-urile rămân utile în fișierele de declarații, pentru a descrie biblioteci globale vechi, și pentru a grupa tipuri înrudite (namespace Api { export interface Elev ... }), caz în care nu generează cod. Un namespace se poate uni cu o clasă, o funcție sau un enum cu același nume (declaration merging).

Exemple

Exemplul 1: Funcții grupate într-un namespace

namespace Geometrie {
    const PI = Math.PI;          // nu este exportat: rămâne intern

    export function arieCerc(r: number): number {
        return PI * r * r;
    }
    export function ariePatrat(l: number): number {
        return l * l;
    }
}

console.log(Geometrie.arieCerc(2).toFixed(2), Geometrie.ariePatrat(3));
console.log(Object.keys(Geometrie));

Rezultat

12.57 9
[ 'arieCerc', 'ariePatrat' ]

Exemplul 2: Namespace doar cu tipuri

Un namespace care conține doar tipuri nu generează niciun cod; este o modalitate de a grupa nume.

namespace Api {
    export interface Elev {
        id: number;
        nume: string;
    }
    export type Raspuns<T> = { ok: true; date: T } | { ok: false; eroare: string };
}

const r: Api.Raspuns<Api.Elev[]> = { ok: true, date: [{ id: 1, nume: "Ana" }] };
if (r.ok) console.log(r.date.map((e) => e.nume));

Rezultat

[ 'Ana' ]

Exemplul 3: Membru neexportat

namespace Geometrie {
    const PI = 3.14159;
    export function arie(r: number) {
        return PI * r * r;
    }
}
console.log(Geometrie.PI);

Eroarea afișată de tsc

exemplu.mts(7,23): error TS2339: Property 'PI' does not exist on type 'typeof Geometrie'.

Greșeli frecvente

  • Folosești namespace-uri în cod nou împărțit pe fișiere. Modulele ES sunt standardul; namespace-urile între fișiere au nevoie de /// <reference> și outFile.
  • Uiți export în interior și te miri că funcția nu se vede din afară.

Comenzi înrudite

  • module și import/export: Fiecare fișier cu import sau export este un modul; exporți funcții, clase și tipuri și le imporți în alte fișiere.
  • declare: Anunță compilatorul că o variabilă, funcție sau modul există deja la rulare, fără să genereze cod pentru ea.
  • fișiere .d.ts: Fișiere care conțin doar tipuri: descriu codul JavaScript ca să poată fi folosit din TypeScript cu verificare.
  • erasableSyntaxOnly: Interzice construcțiile TypeScript care generează cod (enum, namespace, parametri-proprietate), ca Node.js să poată rula direct fișierele .ts.