Typescript在基类中返回工厂方法的类型

时间:2018-01-22 11:52:01

标签: class typescript oop inheritance

来自Python背景,在尝试使用以下继承模型使Typescript满意时遇到了一些问题。

给出以下基类:

// model.ts
export class Model {

    serialize() {}
    static deserialize(dbRow) {}

    static async filter(options) {
        const dbRows = await getData(options);

        return dbRows.map(row => this.deserialize(row));
    }
}

以及以下类扩展它:

// user.ts
export class User extends Model {
    serialize() {......}

    static deserialize(dbRow) {......return new User(......)}

    someOtherMethod() {.....}
}

如何定义Model.filter以便const users = await User.filter({.....})自动将用户类型推断为User []?现在,推断的类型是Model []。

我知道我可以做const users = <User[]> await User.filter({....})但我想知道是否有任何方法可以建议将Model.filter的返回类型作为类构造函数,以便正确推断子类的实例。

2 个答案:

答案 0 :(得分:0)

您可以Model通用:

// model.ts
export class Model<T> {
    ...
    static async filter(options): Array<T> {
        const dbRows = await getData(options);

        return dbRows.map(row => this.deserialize(row));
    }
}

然后:

// user.ts
export class User extends Model<User> {
   ... 
}

您可以阅读有关Typescript&#39}的泛型here的更多信息。

答案 1 :(得分:0)

您可以使用以下解决方法(在this thread中多次提及):

type ModelContructor<T> = new () => T;

class Model {
    // ...
    static async filter<T extends Model>(this: ModelContructor<T> & typeof Model, options): Promise<T[]> {
        const dbRows = await getData(options);

        return dbRows.map(row => this.deserialize(row));
    }
}

此处我们使用假this参数,该T强制UserUser.filter被调用时被解析为1. Download LIBSVM from https://www.csie.ntu.edu.tw/~cjlin/libsvm/. 2. Extract the zip file and paste the folder into Program Files in C Drive. 3. Copy the file path C:\Program Files\libsvm-3.22\java\libsvm.jar. 4. Go to System Properties -> Advanced -> Environment Variables. 5. Click New -> Add Variable Name as CLASSPATH and Add Variable value as C:\Program Files\libsvm-3.22\java\libsvm.jar. 6. Click ok. 7. Open Weka GUI and access LIBSVM.