我正在尝试在Typescript中创建一个通用的MessageBus。我想有一些从父MessageBusMessage类派生的消息类。然后我希望能够订阅此类的消息,并返回此类型的消息。强大的通用打字一路。
这是我到目前为止所做的:
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'));
问题出在消息订阅中。消息的类型是构造函数类型,而不是实际的对象实例类型,因此我从Typescript编译器中获得了类型检查错误:Property 'someValue' does not exist on type 'typeof TestMessage'.
所以我可以看到类型Observable对于getMessageOf的返回类型是错误的。但是什么是正确的类型?如何获取对象实例类型?
答案 0 :(得分:3)
您需要将getMessagesOf<T>
声明为T
的构造函数,而不是T
的实例:
public getMessagesOf<T extends MessageBusMessage>(messageType: new (...args: any[]) => T): Observable<T>