泛型和参数中的 typeof T

11
在TypeScript中,我可以将变量的类型定义为类的类型。例如:
class MyClass { ... }

let myVar: typeof MyClass = MyClass;

现在我想要将它与一个通用类一起使用,类似于这样:
class MyManager<T> {
    constructor(cls: typeof T) { ... }
    /* some other methods, which uses instances of T */
}

let test = new MyManager(MyClass); /* <MyClass> should be implied by the parameter */

因此,我想给我的管理器类另一个类(它的构造函数),因为管理器需要检索与该类相关的静态信息。

当编译我的代码时,它说找不到名称'T',其中我的构造函数在。

有任何解决办法吗?

1个回答

19
您可以使用这种类型的构造函数:{ new (): ClassType }
class MyManager<T> {
    private cls: { new(): T };

    constructor(cls: { new(): T }) {
        this.cls = cls;
    }

    createInstance(): T {
        return new this.cls();
    }
}

class MyClass {}

let test = new MyManager(MyClass);
let a = test.createInstance();
console.log(a instanceof MyClass); // true

(playground中的代码)


编辑

在TypeScript中描述类类型的正确方式如下:

{ new(): Class }

例如,在TypeScript的lib.d.ts中,ArrayConstructor如下所示:lib.d.ts
interface ArrayConstructor {
    new (arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
    (arrayLength?: number): any[];
    <T>(arrayLength: number): T[];
    <T>(...items: T[]): T[];
    isArray(arg: any): arg is Array<any>;
    readonly prototype: Array<any>;
}

在这里,你有三个不同的构造函数签名以及一些静态函数。
在你的情况下,你也可以像这样定义:

interface ClassConstructor<T> {
    new(): T;
}

class MyManager<T> {
    private cls: ClassConstructor<T>;

    constructor(cls: ClassConstructor<T>) {
        this.cls = cls;
    }

    createInstance(): T {
        return new this.cls();
    }
}

3
{ new(): T } 这个东西并不是那么显然,特别是因为构造函数被定义为 constructor(),我们更倾向于期望像 Ttypeof T 或者其他的东西。 - Simon
这是定义类类型/构造函数的标准方式,请查看我修改后的答案以获取更多信息。 - Nitzan Tomer
@NitzanTomer 你会如何编写构造函数以允许 let test = new MyManager(Array<MyClass>); 或者 ...MyManager(MyClass[]); - GFoley83
@GFoley83 你觉得这样怎么样:constructor(cls: MyClassConstrcutor<T>[]) - Nitzan Tomer
@NitzanTomer 我所寻找的是 constructor(cls: { new (...args: any[]): T } []) - GFoley83
@GFoley83 是的,那就是我用一个类型别名写的,没有构造函数参数。 - Nitzan Tomer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接