在Typescript中与联合类型一起使用mixin

在Typescript中与联合类型一起使用mixin,typescript,types,mixins,unions,Typescript,Types,Mixins,Unions,我有一个简单的系统,通过从单独的基类继承类,然后在另一个类中混合到每个基类中来生成类。这是我的混音课: type构造函数=new(…args:any[])=>T; /** *基于此处解释的Mixin思想: * https://mariusschulz.com/blog/typescript-2-2-mixin-classes * *@param-base *@constructor */ 导出函数EntityServices(基:TBase){ 返回类扩展了基{ 私有_组件={}; 公共addC

我有一个简单的系统,通过从单独的基类继承类,然后在另一个类中混合到每个基类中来生成类。这是我的混音课:

type构造函数=new(…args:any[])=>T;
/**
*基于此处解释的Mixin思想:
* https://mariusschulz.com/blog/typescript-2-2-mixin-classes
*
*@param-base
*@constructor
*/
导出函数EntityServices(基:TBase){
返回类扩展了基{
私有_组件={};
公共addComponent(组件:组件){
抛出新错误(“未实现”);
}
公共移除组件(组件:组件){
抛出新错误(“未实现”);
}
};
}
此mixin在另一个模块中用于创建以下几个类:

class ContainerEntityBase扩展了Phaser.GameObjects.Container{}
类ImageEntityBase扩展了Phaser.GameObjects.Image{}
类SpritEntityBase扩展了Phaser.GameObjects.Sprite{}
类TextEntityBase扩展了Phaser.GameObjects.Text{}
export const ContainerEntity=EntityServices(ContainerEntityBase);
export const ImageEntity=EntityServices(ImageEntityBase);
导出常量SpritEntity=EntityServices(SpritEntityBase);
export const TextEntity=EntityServices(TextEntityBase);
//类型定义必须单独导出,以便可以在其他地方用作类型,而不是值
//与值(类)同名并不重要,因为TS将值和类型存储到单独的
//名称空间。
导出类型ContainerEntity=InstanceType;
导出类型ImageEntity=InstanceType;
导出类型spritentity=InstanceType;
导出类型TextEntity=InstanceType;
导出类型BlackbirdEntity=ContainerEntity | ImageEntity | SpritEntity | TextEntity;
如您所见,我已经导出了实际创建的类及其类型,并使用了一个额外的联合类型
BlackBirdEntity
。有时我会使用任何生成类型的变量,因为在这些情况下,这些实例由它们的公共混合接口操作

接下来,我有以下使用union类型的简单定义:

从“../core/Component”导入{Component};
从“../core/entities”导入{BlackbirdEntity};
导出接口IEntityDefinition{
名称:字符串;
组成部分:组成部分[];
类型:黑鸟实体;
}
我这样使用它来创建一个对象,它实现了上述接口:

从“../core/entities”导入{spritentity};
从“/EntityDefinition”导入{IEntityDefinition};
常量clickableEntity:IEntityDefinition={
组成部分:[],
名称:'可点击',
类型:精神性
};
但是,这在突出显示了
spritentity
的IDE上给了我以下错误:

TS2322: Type '{ new (...args: any[]): EntityServices<typeof SpriteEntityBase>.(Anonymous class); prototype: EntityServices<any>.(Anonymous class); } & typeof SpriteEntityBase' is not assignable to type 'BlackbirdEntity'.   Type '{ new (...args: any[]): EntityServices<typeof SpriteEntityBase>.(Anonymous class); prototype: EntityServices<any>.(Anonymous class); } & typeof SpriteEntityBase' is not assignable to type 'EntityServices<typeof TextEntityBase>.(Anonymous class) & TextEntityBase'.     Type '{ new (...args: any[]): EntityServices<typeof SpriteEntityBase>.(Anonymous class); prototype: EntityServices<any>.(Anonymous class); } & typeof SpriteEntityBase' is missing the following properties from type 'EntityServices<typeof TextEntityBase>.(Anonymous class)': _components, addComponent, removeComponent
TS2322:Type'{new(…args:any[]):EntityServices.(匿名类);prototype:EntityServices.(匿名类);}&typeof SpriteEntityBase'不能分配给类型'BlackbirdEntity'。类型“{new(…args:any[]):EntityServices.(匿名类);原型:EntityServices.(匿名类);}&typeof SpritEntityBase”不能分配给类型“EntityServices.(匿名类)&TextEntityBase”。类型“{new(…args:any[]):EntityServices.(匿名类);原型:EntityServices.(匿名类);}&typeof SpritEntityBase”缺少类型“EntityServices.(匿名类)”中的以下属性:_components、addComponent、removeComponent

为什么?以及如何解决此问题?该错误似乎表明
spritentity
缺少在
TextEntity
的父类中实际存在的属性。那么,有没有办法告诉编译器这种类型应该是可以的,即使它们的父级定义不同?

您的问题是
IEntityDefinition
希望它的
type
属性是
BlackbirdEntity
的实例,而不是它的构造函数。您可能会感到困惑,因为对于
而言,构造函数值通常与实例类型共享一个名称,即使如此

无论如何,您已经有了一个
构造函数
类型别名,所以让我们使用它:

export interface IEntityDefinition {
  name: string;
  components: Component[];
  type: Constructor<BlackbirdEntity>; // you want a constructor, not an instance here
}
导出接口IEntityDefinition{
名称:字符串;
组成部分:组成部分[];
type:Constructor;//这里需要的是构造函数,而不是实例
}
这将使
clickableEntity
变量初始化编译时不会出错


希望有帮助;祝你好运

spritentity
没有类型
spritentity
。你的意思是
IEntityDefinition['type']
成为
Constructor
,或者你的意思是将类型
spritentity
的实例作为
clickableEntity
type
属性。是的,我的基本意思是将
spritentity
的一个实例作为
clickableEntity
type
属性。我如何用TS type defs表示这一点?或者如何将类型
spritentity
附加到值
spritentity
?为了澄清,我想将值
spritentity
设置为
可点击实体的属性
类型
。属性应该是entityClass等,而不是类型,因为我希望它引用一个稍后实例化的类。
clickableEntity
对象是工厂的配置对象。因此,在定义
IEntityDefinition
时,您希望使用
Constructor
而不是
BlackbirdEntity
。啊,这绝对有意义!由于某种原因,我没有意识到我必须将类型指定为构造函数,并且意外地使用了一个实例。非常感谢。