modul - TypeScript: Hur man använder intern gränssnitt inom namnrymden


Jag har ett gränssnitt som jag bara vill använda inom ett namnrum (internt modul) och det bör inte användas utanför namnrymden.

Exempelgränssnitt:

namespace Test {
    interface IInterface {
        getId(): number;
        getName(): string;
    }
}

Tyvärr får jag ett fel när jag försöker implementera detta gränssnitt inom samma namnrymd om jag inte exporterar gränssnittet (vilket jag inte vill).

Implementerande klass:

namespace Test {
    class Implementer implements IInterface {
        private location: Location;

        public getId(): number {
            return 1;
        }

        public getName(): string {
            return "implementer name";
        }
    }
}

Vilket ger: TS2304: Kan inte hitta namnet 'IInterface'. i 'Implementer.ts'.

Observera den privata medlemmen av typen 'Location' som också är en ny typ/klass definierad av mig själv i samma namnrymd och det är den faktiska anledningen till att använda namnrymder eftersom typen 'Location' redan finns i det globala utrymmet.

Clas med konfliktande namn om den används utanför namnrymden:

namespace Test {
    class Location {
        private name: string = null;
        constructor(name: string) {
            this.name = name;
        }
    }
}

Dessutom: Jag använder inga moduler och jag konverterar vissa typer från JavaScript till TypeScript-klasser. Att använda /// <reference path="IInterface.ts" />-hjälpen fungerar inte (och är inte problemet här). Jag vill inte heller införa någon modul-laddare.

Så hur använder jag mitt gränssnitt i samma namnrymd utan att exportera det?

Svar #1

Jag svarar först på den sista frågan: "Klass med motsägelsefullt namn om den används utanför namnrymden". Ett globalt objekt Location finns redan i webbläsaren. Du kan använda detta namn för din klass i en modul eller i en namnrymd. Annars måste du välja ett annat namn.

Sedan vill du dela ett namespace. Bara export medlemmen IInterface för att exponera den utanför IIFE:

namespace Test {
    export interface IInterface {
        getId(): number;
        getName(): string;
    }
}

Förklaring

Från handboken:

Namespaces är helt enkelt namngivna JavaScript-objekt i det globala namnområdet.

Här är en illustration (se koden i TS Playground):

namespace Test {
  export let name = 'abc'
}

namespace Test {
  let message = 'Hello, ' + name;
}

Efter kompileringen, här är JavaScript-koden:

var Test;
(function (Test) {
    Test.name = 'abc';
})(Test || (Test = {}));

var Test;
(function (Test) {
    var message = 'Hello, ' + Test.name;
})(Test || (Test = {}));

Namnområdet Test är ett "enkelt namngivet JavaScript-objekt i det globala namnområdet". Du kan se att variabeln message inte kunde återanvändas utanför sin IIFE. Även om vi skapar en tredje IIFE för samma globala variabel (namnområde) Test.

Relaterade artiklar