簡體   English   中英

Typescript:將泛型類傳遞給函數參數

[英]Typescript: Pass generic class to function parameter

我需要將class reference作為function parameter傳遞,並在此類上調用static method 將來,我可能需要創建類的實例並添加構造函數作為示例。

我沒有打字工作:

class Messages {
    getMessage(classRef: any): any {
       return classRef.getMessage()
     }
}

class myClassA {
    constructor(public id: number, public message: string) {}
    static getMessage(): string {
        return 'hello from class A';
    }
}

class myClassB {
    constructor(public id: number, public message: string) {}
    static getMessage(): string {
        return 'hello from class B';
    }
}

var messages = new Messages();
var messageA = messages.getMessage(myClassA);
var messageB = messages.getMessage(myClassB);

console.log(messageA) // 'hello from class A'
console.log(messageB) // 'hello from class B'

我試圖鍵入類引用,可能與泛型,但混淆如何去做。

我嘗試按照getMessage<C>(classRef: {new(): C;}): any {}...做一些事情getMessage<C>(classRef: {new(): C;}): any {}...但這些都沒有用。

有人可以解釋我如何正確傳遞課程參考?

一般來說,您必須使用構造函數類型引用typescript中的類。 但是,從typescript 2.8開始,標准庫中有一個新的InstanceType<T>類型,可以從構造函數類型中提取實例類型。 您可以在此處使用它來獲得所需的類型安全性。

對於您的代碼段,您可以添加如下類型:

class Messages {
    getMessage<T extends {getMessage: () => string, new (...args: any[]): InstanceType<T>}>(classRef: T): string {
       // Here, classRef is properly inferred to have a `getMessage` method.
       return classRef.getMessage()
    }
}

class myClassA {
    constructor(public id: number, public message: string) {}
    static getMessage(): string {
        return 'hello from class A';
    }
}

class myClassB {
    constructor(public id: number, public message: string) {}
    static getMessage(): string {
        return 'hello from class B';
    }
}

var messages = new Messages();

// messageA and messageB inferred to have type: string
// You can change that back to any if you want.

// myClassA and myClassB both assignable as the argument to
// getMessage, so no problem there.
var messageA = messages.getMessage(myClassA);
var messageB = messages.getMessage(myClassB);

console.log(messageA) // 'hello from class A'
console.log(messageB) // 'hello from class B'

這條線

getMessage<T extends {getMessage: () => string, new (...args: any[]): InstanceType<T>}>(classRef: T): string {

是類型安全的來源。 該語法說無論T是什么,它都必須有一個方法getMessage (所以如果T是一個類構造函數, getMessage必須是一個靜態方法),那么new (...args: any[]): InstanceType<T>表示T必須是類構造函數。

我已經將構造函數的參數設置為此處的任何內容,但是如果您知道構造函數將始終采用特定參數,則可以進一步縮小它。 對於您的示例, new (id: number, message: string): InstanceType<T>將起作用。


如果沒有typescript 2.8,則無法使用InstanceType 但是,通過讓T表示實例類型,然后將參數的類型設置為使用T作為其參數的包裝類型,您仍然可以獲得類型安全性。 所以對於你的例子:

interface Messageable<T> {
    new(...args: any[]): T;
    getMessage(): string;
}

class Messages {
    getMessage<T>(classRef: Messageable<T>): string {
       return classRef.getMessage()
    }
}

應該管用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM