Thi*_*ibs 3 typescript typescript2.0
我需要通过一个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'
Run Code Online (Sandbox Code Playgroud)
我试图键入类引用,可能使用泛型,但对如何执行此操作感到困惑。
我尝试做一些事情,getMessage<C>(classRef: {new(): C;}): any {}...但是没有任何效果。
有人可以解释一下我如何正确地通过课堂参考吗?
一般来说,您必须使用其构造函数类型来引用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'
Run Code Online (Sandbox Code Playgroud)
线
getMessage<T extends {getMessage: () => string, new (...args: any[]): InstanceType<T>}>(classRef: T): string {
Run Code Online (Sandbox Code Playgroud)
是类型安全性的来源。该语法表明,无论如何T,它都必须具有一个方法getMessage(因此,如果T是一个类构造函数,getMessage则必须是一个静态方法),而new (...args: any[]): InstanceType<T>意味着它T必须是一个类构造函数。
我已经将构造函数的参数设置为此处的任何值,但是如果您知道构造函数将始终采用特定的参数,则可以进一步缩小范围。对于您的示例,new (id: number, message: string): InstanceType<T>将工作。
如果没有打字稿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()
}
}
Run Code Online (Sandbox Code Playgroud)
应该管用。
| 归档时间: |
|
| 查看次数: |
3771 次 |
| 最近记录: |