Typescript允许使用mixins进行适当的多重继承,但无法创建声明文件

问题描述 投票:1回答:1

我正在玩TypeScript中的“多重继承”,或者更好地理解mixins。经过许多弯路,我发现最简单的方法是尽可能少的显式铸造,并能够创建如下所示的东西(完整的例子可以在这个gist中找到)。

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

export function TaggedMixin<Super extends Ctor>(superClass: 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;

        this.anon_public;
        this.anon_protected;
        this.tag_public;
        this.tag_protected;
    }
}


编辑:

该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)
typescript multiple-inheritance encapsulation mixins
1个回答
2
投票

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

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

Typescript将mixin的实例类型表示为对象类型,并且对象类型不能使用privateprotected标记成员,因此会出错。

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

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

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.