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