2017-07-20 29 views
0

我試圖在Typescript中創建一個通用MessageBus。我想要有一些從父MessageBusMessage類派生的消息類。然後,我希望能夠訂閱此類的消息,並返回此類消息。強泛型打字一路。在Typescript中使用泛型MessageBus時發生類型錯誤(使用rxjs)

這是我到目前爲止有:

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')); 

的問題是消息訂閱內。該消息的類型是構造類型,而不是實際的對象實例的類型,所以我得到一個類型從打字稿編譯器檢查錯誤:Property 'someValue' does not exist on type 'typeof TestMessage'.

這樣我就可以看到可觀測的類型是如何錯誤的getMessageOf的返回類型。但是什麼是正確的類型?如何獲取對象實例類型?

回答

2

需要聲明getMessagesOf<T>如服用了T構造函數,而不是T一個實例:

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

是啊。這工作。你在這裏幫了我很多。我花了好幾個小時試圖讓自己的工作。 – Sammi