【问题标题】:Type error when making generic MessageBus in Typescript (with rxjs)在 Typescript 中制作通用 MessageBus 时出现类型错误(使用 rxjs)
【发布时间】:2017-07-20 09:33:10
【问题描述】:

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

【问题讨论】:

    标签: typescript rxjs


    【解决方案1】:

    您需要将getMessagesOf&lt;T&gt; 声明为采用T 的构造函数,而不是T 的实例:

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

    【讨论】:

    • 是的。那行得通。你在这里真的帮了我很多。我已经花了好几个小时试图自己完成这项工作。
    猜你喜欢
    • 1970-01-01
    • 2018-10-29
    • 2017-02-20
    • 2020-09-15
    • 1970-01-01
    • 2016-08-28
    • 2019-09-02
    • 2016-10-02
    • 1970-01-01
    相关资源
    最近更新 更多