[英]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.