在Typescript中将泛型类型传递给mixin

在Typescript中将泛型类型传递给mixin,typescript,generics,mixins,Typescript,Generics,Mixins,我正在尝试在Typescript中创建泛型混合。据我所知,从dev版本2.8.0开始,Typescript还没有直接支持这一点。我在找一个解决办法。我不在乎mixin本身有多丑陋,只要应用mixin是干净和可读的 我需要在一些mixin中提供decorator支持,因此我将mixin定义为嵌套类,并以其为模型。更常见的方法。我还没有注意到嵌套类方法中丢失了任何功能 我特别希望在外部mixin中指定泛型类型,以确定在更多嵌套mixin中找到的类型,至少在外部mixin外部查看时是这样。我意识到,可

我正在尝试在Typescript中创建泛型混合。据我所知,从dev版本2.8.0开始,Typescript还没有直接支持这一点。我在找一个解决办法。我不在乎mixin本身有多丑陋,只要应用mixin是干净和可读的

我需要在一些mixin中提供decorator支持,因此我将mixin定义为嵌套类,并以其为模型。更常见的方法。我还没有注意到嵌套类方法中丢失了任何功能

我特别希望在外部mixin中指定泛型类型,以确定在更多嵌套mixin中找到的类型,至少在外部mixin外部查看时是这样。我意识到,可能需要一种截然不同的方法来处理Typescript可能无法通过嵌套函数调用向下传递外部函数中定义的类型的可能性

给定以下代码:

interface-ConcreteClass{new(…args:any[]):C;}
类实体{
name=“base”;
}
阶级经纪人{
静态表=“实体”;
}
接口BrokerType扩展了ConcreteClass{
表:字符串;
}
类标识扩展了实体{
id=1;
}
函数IdMixin(基:B){
类AsIdBroker扩展了基{
构造函数(…参数:任意[]){
超级(…args);
}
getEntity(id:number):E | null{
返回null;
}
}
返回ASIDBRAKER;
}
类标记标识扩展了标识{
tag=“gotcha”;
}
下面是一个理想的方法,但这不起作用:

//选项A——坏了
类TaggedBroker扩展了代理{};
类MyTaggedBroker扩展了IdMixin(TaggedBroker){
myStuff=“堆积”;
showTag(id:number){
const entity=this.getEntity(id);
if(实体){
//错误:类型“IdEntity”上不存在属性“tag”。
console.log(entity.tag);
}
}
}
我也很乐意这样做,但这也不行:

//选项B——已断开
类TaggedBroker扩展了代理{};
//错误:应为2个类型参数,但得到1个。
类MyTaggedBroker扩展了IdMixin(TaggedBroker){
myStuff=“我的一切”;
showTag(id:number){
const entity=this.getEntity(id);
if(实体){
console.log(entity.tag);
}
}
}
最后一种方法使当前的所有代码都能工作,但除了冗长(至少在我的应用程序中有名称)之外,它没有继承基本代理的类型,因此不是真正的混合:

//选项C——在这里工作,但删除以前混合在代理中的任何类型
类TaggedBroker扩展了代理{};
类MyTaggedBroker扩展了IdMixin(TaggedBroker){
myStuff=“我的一切”;
showTag(id:number){
const entity=this.getEntity(id);
if(实体){
console.log(entity.tag);
}
}
}

我在这里发帖,以防有人知道我需要做什么。同时,我将继续探索我的选项,可能包括一种IoC方法,首先键入嵌套的most mixin。

要使选项C能够继承成员从
TaggedBroker
MyTaggedBroker
,您只需要一个简单的更改:

class TaggedBroker extends Broker<TaggedEntity> { 
    public x: number;
};

class MyTaggedBroker extends IdMixin<TaggedEntity, typeof TaggedBroker>(TaggedBroker) {
    myStuff = "all mine";
    showTag(id: number) {
        console.log(this.x);
        const entity = this.getEntity(id);
        if (entity) {
            console.log(entity.tag);
        }
    }
}

因此,选项C的问题是,如果您将成员添加到
TaggedBroker
中,它们不会继承到
MyTaggedBroker
?天哪,你是个魔术师!这两种方法确实使这个例子起作用。现在把它合并到我的库中,看看我是否遗漏了什么。非常感谢你!一会儿就回来了…太棒了!这是一个简单的改变,所有的测试都通过了,而且它可以在多个深度混合中工作。谢谢你为我节省了几小时甚至几天的生命!在mixin中保存抽象类行为不会有什么魔力,是吗?我可以先将抽象类转换为具体的构造函数,但编译器不会告诉我类表达式何时无法实现抽象属性;让类表达式实现具有这些缺失属性的接口也无济于事——它们仍然未报告。据说什么也做不了:毕竟我有
返回类扩展基本实现AbstractClassInterface
。只要我记得实现接口,我就会得到检查。如果您使用此签名定义
IdMixin
(注意默认类型参数):
函数IdMixin(Base:B)
,那么您就不需要
typeof TaggedBroker
类型参数。
function IdMixin<E extends IdEntity>()  {
    return function <B extends BrokerType<E>>(Base: B){
        class AsIdBroker extends Base {
            constructor(...args: any[]) {
                super(...args);
            }
            getEntity(id: number): E | null {
                return null;
            }
        }
        return AsIdBroker;
    }
}
//Usage
class MyTaggedBroker extends IdMixin<TaggedEntity>()(TaggedBroker) {
    // Same as before
}