I'm currently working on developing a versatile MessageBus in Typescript. My goal is to create message classes that inherit from a main MessageBusMessage class, allowing for subscription to messages of a specific class type with strong generic typing throughout.
Here's what I have so far:
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/filter';
export class MessageBusMessage {
}
export class TestMessage extends MessageBusMessage {
constructor(public readonly someValue: string) {
super();
}
}
export class MessageBus {
private subject: Subject<MessageBusMessage>;
constructor() {
this.subject = new Subject();
}
public publish(message: MessageBusMessage) {
this.subject.next(message);
}
public getMessagesOf<T extends MessageBusMessage>(messageType: T): Observable<T> {
return this.subject.filter( (message) => {
return (message.constructor as any).name === (messageType as any).name;
}) as any;
}
}
const messageBus = new MessageBus();
const subscription = messageBus.getMessagesOf(TestMessage).subscribe(
(message) => {
console.log('got test message', message.someValue);
}
)
messageBus.publish(new TestMessage('some test value'));
However, I've encountered an issue with the message subscription. The type of the message is showing as the constructor type rather than the actual object instance type, resulting in a type checking error from the Typescript compiler:
Property 'someValue' does not exist on type 'typeof TestMessage'.
It seems that the observable type is incorrect for the return type of getMessageOf. But what should the correct type be? How can I access the object instance type?