在Typescript中创建通用MessageBus时输入错误(使用rxjs)

时间:2017-07-20 09:33:10

标签: typescript rxjs

我正在尝试在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的返回类型是错误的。但是什么是正确的类型?如何获取对象实例类型?

1 个答案:

答案 0 :(得分:3)

您需要将getMessagesOf<T>声明为T的构造函数,而不是T的实例:

public getMessagesOf<T extends MessageBusMessage>(messageType: new (...args: any[]) => T): Observable<T>