Typescript允许对混合使用正确的多重继承,但无法创建增量文件

Typescript允许对混合使用正确的多重继承,但无法创建增量文件,typescript,multiple-inheritance,encapsulation,mixins,Typescript,Multiple Inheritance,Encapsulation,Mixins,我在TypeScript中玩弄“多重继承”,或者更确切地说是对mixin有了很好的理解。经过许多弯路,我发现最简单的方法是尽可能少的显式转换,并且能够创建如下所示的内容(完整的示例可以在本文中找到) 我的问题是:为什么TypeScript允许我构建它,但却无法为此创建声明文件 导出函数TaggedMixin(超类:Super){ 类标记扩展了超类{ 公共静态标记\公共:字符串; 受保护的静态标记\u受保护:字符串; private static TAG_private:string; publi

我在TypeScript中玩弄“多重继承”,或者更确切地说是对mixin有了很好的理解。经过许多弯路,我发现最简单的方法是尽可能少的显式转换,并且能够创建如下所示的内容(完整的示例可以在本文中找到)

我的问题是:为什么TypeScript允许我构建它,但却无法为此创建声明文件

导出函数TaggedMixin(超类:Super){
类标记扩展了超类{
公共静态标记\公共:字符串;
受保护的静态标记\u受保护:字符串;
private static TAG_private:string;
public tag_public!:字符串;
受保护标签\u受保护!:编号;
私人标签_private!:编号;
}
返回标记;
}
常量taged=TaggedMixin(类{
public static ANON_public:string;
受保护的静态ANON_受保护:字符串;
private static ANON_private:string;
public anon_public!:字符串;
受保护的和不受保护的!:编号;
private anon_private!:编号;
});
类TaggedClass扩展了taged{
构造函数(){
超级();
TaggedClass.ANON_PUBLIC;
TaggedClass.ANON_受保护;
TaggedClass.TAG_PUBLIC;
TaggedClass.TAG_受保护;
这是不公开的;
这是不受保护的;
这个标签是公共的;
此标记受保护;
}
}
编辑:

TS无法创建声明文件的错误:

Property 'tag_protected' of exported class expression may not be private or protected.ts(4094)
Property 'tag_private' of exported class expression may not be private or protected.ts(4094)
Property 'TAG_PROTECTED' of exported class expression may not be private or protected.ts(4094)
Property 'TAG_PRIVATE' of exported class expression may not be private or protected.ts(4094)

发出声明和混合存在一些限制。类表达式不能有私有或受保护的成员,因为如上所述:

如果启用了声明emit,则导出的匿名类不能有私有或受保护的成员,因为无法在.d.ts文件中表示这些成员

Typescript将mixin的实例类型表示为对象类型,并且对象类型不能将成员标记为
private
protected
,因此出现错误

删除非公共成员将解决此问题

您还可以添加一些手动键入和类声明,这将使您接近您的目标:

type Ctor = new (...a: any[]) => any
declare class TaggedMixinInstance { // just a dummy, never call new TaggedMixinInstance() or extend this directly 
    public tag_public: string;
    protected tag_protected: number;
    private tag_private: number;
}

export function TaggedMixin<Super extends Ctor>(superClass: Super): {
    new(...a: any[]): TaggedMixinInstance;
    TAG_PUBLIC: string
} & Super {
    class Tagged extends superClass {
        public static TAG_PUBLIC: string;
        protected static TAG_PROTECTED: string;
        private static TAG_PRIVATE: string;

        public tag_public!: string;
        protected tag_protected!: number;
        private tag_private!: number;
    }

    return Tagged;
}

const Tagged = TaggedMixin(class {
    public static ANON_PUBLIC: string;
    protected static ANON_PROTECTED: string;
    private static ANON_PRIVATE: string;

    public anon_public!: string;
    protected anon_protected!: number;
    private anon_private!: number;
});

class TaggedClass extends Tagged {
    constructor() {
        super();

        TaggedClass.ANON_PUBLIC;
        TaggedClass.ANON_PROTECTED;
        TaggedClass.TAG_PUBLIC;
        TaggedClass.TAG_PROTECTED; // still an error

        this.anon_public;
        this.anon_protected;
        this.tag_public;
        this.tag_protected;
    }
}
type-Ctor=new(…a:any[])=>any
声明类TaggedMixinInstance{//只是一个伪类,不要调用新的TaggedMixinInstance()或直接扩展它
public tag_public:字符串;
受保护标签\u受保护:编号;
私有标签\私有:编号;
}
导出函数TaggedMixin(超类:Super):{
新(…a:any[]):TaggedMixinInstance;
TAG_PUBLIC:string
}&Super{
类标记扩展了超类{
公共静态标记\公共:字符串;
受保护的静态标记\u受保护:字符串;
private static TAG_private:string;
public tag_public!:字符串;
受保护标签\u受保护!:编号;
私人标签_private!:编号;
}
返回标记;
}
常量taged=TaggedMixin(类{
public static ANON_public:string;
受保护的静态ANON_受保护:字符串;
private static ANON_private:string;
public anon_public!:字符串;
受保护的和不受保护的!:编号;
private anon_private!:编号;
});
类TaggedClass扩展了taged{
构造函数(){
超级();
TaggedClass.ANON_PUBLIC;
TaggedClass.ANON_受保护;
TaggedClass.TAG_PUBLIC;
TaggedClass.TAG_PROTECTED;//仍然是错误
这是不公开的;
这是不受保护的;
这个标签是公共的;
此标记受保护;
}
}

您能详细说明一下“无法创建声明文件”的含义吗?您确定声明文件中包含了您未导出的内容吗?我在问题中添加了错误输出。这个例子是完整的,没有其他出口或进口的东西。是的,经过长时间的研究,这就是我发现的。然而,我想知道为什么他们说他们支持mixin类,却忘了提到这个重要的事情。TypeScript团队是否有任何理由?他们是否打算添加它,或者这是一个没有人真正需要的东西,所以没有文档记录?编译器给您的错误消息告诉您这里不能使用私有和受保护的方法。你可以说错误信息是文档,只是没有解释为什么不可能。@FlorianBachmann关于这一点有一个开放的问题,所以它可能会发生。我添加了一个您可能会发现的解决方法useful@TitianCernicova-德拉戈米尔:这是一个很好的解决办法。我会关注这个问题:)