如何使用作为参数传递的类的静态函数

时间:2019-12-20 14:11:43

标签: typescript class types

基本上,我需要使用作为参数传递的类的静态函数:

编辑:

我没有正确解释自己,希望您能通过此示例理解我。

  

最小可复制示例。

const TABLES = {
  bike: [],
  car: []
};

class Vehicles {
  static table = "";
  static getAll<T extends Vehicles>(): T[] {
    return TABLES[this.table];
  }
}

class Bike extends Vehicles {
  static table = "bike";
}

class Car extends Vehicles {
  static table = "car";
}

function getVehicleByClass<T extends Vehicles>(Vehicle: typeof T) { // 'T' only refers to a type, but is being used as a value here.
  Vehicle.getAll();
}

getVehicleByClass<Car>(Car);

1 个答案:

答案 0 :(得分:1)

更新的答案

...在修改问题之后。

通用类型应扩展typeof Vehicles而不是Vehicles

function getVehicleByClass<T extends typeof Vehicles>(Vehicle: T) {
  Vehicle.getAll();
}

On the playground

也就是说,我可以给自己输入typeof Vehicles的类型:

type VehiclesType = typeof Vehicles;

然后:

function getVehicleByClass<T extends VehiclesType>(Vehicle: T) {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
  Vehicle.getAll();
}

On the playground

...只是因为我认为小块更好。 :-D

原始答案

(我只留下这个是因为您说它对于您正在工作的其他某些东西很有用...)

您应该使用的东西,我怀疑这里的真正问题是您没有键入Object.values(在ES2017中添加)。您需要检查tsconfig.json以确保您的lib选项为ES2017或更高版本。

如果您输入的是Object.valuesthis works

class Model {
    static associate(models: { [key: string]: typeof Model }): { [key: string]: typeof Model } {
        return { foo: Model };
    }
}
class Model2 extends Model {
}
class Model3 extends Model {
}

async function createAssociations(models: { [key: string]: typeof Model }): Promise<void> {
  Object.values(models).forEach(model => {
    if (model.associate) {
      model.associate(models);
    }
  });
}

...尽管我认为我会为该{[key: string]: typeof Model}类型使用一种类型,因为您在多个地方都使用了它:

type ModelValuesObject = { [key: string]: typeof Model };

然后:

class Model {
    static associate(models: ModelValuesObject): ModelValuesObject {
        return { foo: Model };
    }
}
class Model2 extends Model {
}
class Model3 extends Model {
}

async function createAssociations(models: ModelValuesObject): Promise<void> {
  Object.values(models).forEach(model => {
    if (model.associate) {
      model.associate(models);
    }
  });
}

如果要最小更改,可以在model回调中键入forEach参数:

Object.values(models).forEach((model: typeof Model) =>

这将允许您在static值的类上使用model方法。

但是TypeScript可以推断出它。在这里,我使用了{[key: string]: typeof Model}并给它起了方便的名字,以便我们重新使用它:

type ModelValuesObject = { [key: string]: typeof Model };

那就是

class Model {
    static associate(models: ModelValuesObject): ModelValuesObject {
        return { foo: Model };
    }
}
class Model2 extends Model {
}
class Model3 extends Model {
}

async function createAssociations(models: ModelValuesObject): Promise<void> {
  Object.values(models).forEach(model => {
    if (model.associate) {
      model.associate(models);
    }
  });
}

On the playground