Typescript:构造函数的散列

Typescript:构造函数的散列,typescript,Typescript,我有一个表示数据模型的抽象类。让我们称之为模型。它实际上是在ModelData类型中参数化的,该类型表示模型实际拥有的数据类型。因此: export interface ModelData { type: string; attributes: {} } export class Model<D extends ModelData> {} export interface UserData extends ModelData { type: 'users', attribute

我有一个表示数据模型的抽象类。让我们称之为模型。它实际上是在ModelData类型中参数化的,该类型表示模型实际拥有的数据类型。因此:

export interface ModelData { type: string; attributes: {} }
export class Model<D extends ModelData> {}
export interface UserData extends ModelData 
  { type: 'users', attributes: { name: string; }}
export class Users extends Model<UserData> {}
然后

find<T extends ModelData>(ref: ModelReference): Model<T> {
  return new types[ref.type]({id: ref.id})
}
find(ref:ModelReference):模型{
返回新类型[ref.type]({id:ref.id})
}
或多或少(为了简洁起见,省略了额外的空保护和其他代码)

这实际上是不正确的-我实际返回的是
扩展模型
,并且我存储在类型中的不是
模型的类型
,而是
扩展模型的类型

在2.4.1之前(我假设这与隐式泛型更改有关),代码编译时毫无怨言,尽管不正确。我很高兴它正确无误,但我不确定如何使用typescript来表达这一点

我得到的具体内容是一组
ModelData
类型,它们为ModelData的属性和关系属性定义了不同的形状,以及一组为这些ModelData类型中的每一种扩展模型的类。因此,从技术上讲,我可以返回一个模型,但我宁愿返回一个用户,因为我可能会增加一些额外的方便在用户上添加新方法


那么,有没有可能说,“这个东西包含一个字符串索引的构造函数组,所有这些构造函数都遵循“extends AbstractClass”的模式?”

我建议这样做:

const types = {
  'users': Users,
  // ... other Models
}

function find<K extends keyof typeof types>(ref: { type: K }): typeof types[K]['prototype'] {
  return new types[ref.type](); // this only works if all Models have no-arg constructors
}
如果我想说“这个对象的值是适当的
模型
类型的构造函数,其中键与
ModelData['type']
值相同”,我会说:

type ModelMap<T> = {
  [K in keyof T]: Constructor<Model<ModelData & { type: K }>>
}
function verifyTypes<T>(types: T, alsoTypes: ModelMap<T>) { }
verifyTypes(types, types);
请注意,只有当您的
Model
类型实际上保留了正确的
ModelData
类型的某些属性时,编译器才会生气。如果它们如示例所示为空,则您的所有类型在结构上都是相同的,编译器永远不会抱怨:

export class Model<D extends ModelData> { 
  data: D; // that's enough 
}
导出类模型{
data:D;//够了
}

希望这能有所帮助。祝你好运!

hmm,这更接近我的需要。有没有办法将类型用作实例变量,这样我就可以执行
查找
?(这不是现成的)。这让我可以在数据存储的子类中定义真正的类型(数据存储是泛型的,子类添加具体的、特定于项目的数据类型)您可以尝试
this['types']
而不是
typeof this.types
,但是我认为
这个
多态性可能会使这个问题产生。如果你的类名是
DataStore
并且它有一个
types
属性,那么你可以使用
DataStore['types']
而不是
typeof this.types
type ModelMap<T> = {
  [K in keyof T]: Constructor<Model<ModelData & { type: K }>>
}
function verifyTypes<T>(types: T, alsoTypes: ModelMap<T>) { }
verifyTypes(types, types);
const types = {
   'user': Users
}
verifyTypes(types, types); // error: type of property 'user' is incompatible
export class Model<D extends ModelData> { 
  data: D; // that's enough 
}