2016-12-04 3 views
-1

Ich bin ein TypScript-Neuling und das folgende ist eine Frage der Neugier meist.Definieren Sie Klassen ohne das Klassenschlüsselwort in Typoskript zu verwenden

Vor ES6 hatte JavaScript keine Klassen. Daher würde ich davon ausgehen können, dass ich nicht mit TypeScript arbeiten kann.

Doch ich finde nicht den richtigen Weg, es zu tun. Nehmen Sie diese Beispielklasse:

class FooConcrete { 
    getImpl :() => number; 

    constructor(getImpl:() => number) { 
     this.getImpl = getImpl; 
    } 

    get() : number { 
     return this.getImpl(); 
    } 
} 

Da Typ-Definitionsdateien in der Regel so etwas wie die folgenden aussetzen, ich damit anfangen:

interface FooConcrete 
{ 
    get() : number; 
} 

interface FooConcreteStatic 
{ 
    new() : FooConcrete; 
} 

Aber wie definiere ich dann den Konstruktor Funktion FooConcrete?

Ich habe versucht:

var FooConcrete : FooConcreteStatic = function FooConcrete() { 
    return { 
     get:() => 42 
    }; 
}; 

Das ist nicht jedoch nicht kompiliert, obwohl die entsprechenden Javascript funktioniert wie beabsichtigt:

new FooConcrete().get() // => 42 

Gibt es eine Möglichkeit FooConcrete als FooConcreteStatic zu erklären, ohne sie als Schreib Klasse?

(Die Motivation hinter dem Fall war, dass ich war gespannt, ob es eine Möglichkeit der unechten Umleitung in der Klasse des Prototyp des loszuwerden war get zur Umsetzung getImpl - in diesem Fall gibt es keine Notwendigkeit für ein get in einem Prototyp.)

Antwort

0

Ich bin ziemlich sicher, dass Sie das nicht tun können, ohne den Compiler zu tricksen, weil die Sprache die Arbeit für Sie erledigt, wenn Sie Klassen verwenden.

Ihr Typoskript Klassencode:

class FooConcrete { 
    getImpl :() => number; 

    constructor(getImpl:() => number) { 
     this.getImpl = getImpl; 
    } 

    get() : number { 
     return this.getImpl(); 
    } 
} 

in diese kompiliert, wenn ES5-Targeting:

var FooConcrete = (function() { 
    function FooConcrete(getImpl) { 
     this.getImpl = getImpl; 
    } 
    FooConcrete.prototype.get = function() { 
     return this.getImpl(); 
    }; 
    return FooConcrete; 
}()); 

Und die Definitionsdatei:

declare class FooConcrete { 
    getImpl:() => number; 
    constructor(getImpl:() => number); 
    get(): number; 
} 

Die js Ausgang ist ziemlich viel, was Sie wollte tun (nur mit Prototyp, der ist der "richtige" Weg zu gehen), und die Definition verwendet declare class und nicht mit Schnittstellen, wie Sie darauf hingewiesen haben.

Dieser Ansatz führt zu saubererem Code und der Möglichkeit, ihn in ES5-Klassen oder ES6-Klassen zu kompilieren.

Verwandte Themen