2016-04-26 3 views
0

Ich versuche, einfache Ereignis Bus-Klasse in Typescript zu entwickeln, wo es möglich ist, Ereignisse zu veröffentlichen und abonnieren Sie. Es wird nett sein, eine Bindung zwischen veröffentlichtem Thema und der Schnittstelle der veröffentlichten Daten zu haben. Ich habe versucht, dies mit Hilfe von Funktions- und Klassengenerika zu erreichen, jedoch funktionieren einige meiner Testfälle nicht wie erwartet (in einer Weise, dass die Zeilen, die ich erwarten würde, fehlerhaft kompiliert werden). Ich habe auch ein Beispiel hinzugefügt von: https://www.typescriptlang.org/docs/handbook/generics.html , die wie erwartet funktioniert. In der realen Welt plane ich, dass Instanzen von Themen irgendwo als Singletons gespeichert werden.Typescript generische Funktionen nicht wie erwartet funktioniert - Parameter enthält einen anderen generischen Typ als erforderlich, kompiliert OK

interface BaseMessage { }; 
interface MyMessage extends BaseMessage { 
    a: number; 
}; 
interface MyMessage2 extends BaseMessage { 
    b: string; 
} 
class Topic<A> {} 
class MyTopic extends Topic<MyMessage> { }; 
class MyTopic2 extends Topic<MyMessage2> { }; 
class MyTopic3 extends Topic<MyMessage2> { }; // example of another topic using the same message interface 

class EventBus { 
    publish<T extends BaseMessage> (topic: Topic<T>, data: T): void {} 
    subscribe<T extends BaseMessage>(topic: Topic<T>, callback: (arg?: T) => void): void { } 
    loggingIdentity<T>(arg: Array<T>): Array<T> { 
     return arg; 
    } 
    loggingIdentity2<T>(arg: Topic<T>): Topic<T> { 
     return arg; 
    } 
} 
class Test { 
    init(): void { 
     let eb = new EventBus(); 
     eb.loggingIdentity<MyMessage2>(new Array<MyMessage2>()); // works just fine 
     eb.loggingIdentity<MyMessage2>(new Array<MyMessage>()); // error as expected 
     eb.loggingIdentity2<MyMessage2>(new Topic<MyMessage2>()); // works just fine 
     eb.loggingIdentity2<MyMessage2>(new Topic<MyMessage>()); // I am expecting this to fail, but this works 
     eb.publish<MyMessage2>(new MyTopic2(), { a: 1 }); // fails on not satisfying data parameter interface - expected 
     eb.publish<MyMessage2>(new MyTopic2(), { b: "hello" }); // works just fine 
     eb.publish<MyMessage2>(new MyTopic(), { b: "hello" }); // I am expecting this to fail, because of the first parameter, but it works 
    } 
} 

Vielleicht fehlt mir da etwas. Jede Hilfe wäre dankbar, danke.

Antwort

1

hier:

class Topic<A> {} 

Die Klasse Topic nicht den generischen Typ nicht verwendet A. So sind Topic<SomethingHere> und Topic<SomethingElse> kompatibel.

Verwenden der generische Typ A und die Fehler auftreten, wie erwartet:

class Topic<A> { abc: A; } 
+0

Dank, es funktioniert, ist es ausreichend, Klasse Thema auf diese Weise zu aktualisieren: Klasse Topic {private Mitglied: A } –

Verwandte Themen