Typescript позволяет использовать правильное множественное наследование с миксинами, но не может создавать файлы делкарации - PullRequest
1 голос
/ 19 марта 2019

Я играл с «множественным наследованием» в TypeScript или, скорее, получал хорошее представление о миксинах. После многих обходных путей, я обнаружил, что самый простой способ - это как можно меньше явных приведений и создать материал, как показано ниже (полные примеры можно найти в этом 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)

1 Ответ

2 голосов
/ 19 марта 2019

Существуют ограничения на создание объявлений и миксины.Выражения классов не могут иметь закрытых или защищенных членов, потому что, как указано здесь :

экспортируемые анонимные классы не могут иметь закрытых или защищенных членов, если включена декларация 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;
    }
}
...