BonBonSlick
@BonBonSlick
Junior Web Developer Trainee

Как использовать миксины на асбтрактные классы?

// https://www.typescriptlang.org/docs/handbook/mixins.html

type Constructor<T = {}> = new (...args: any[]) => T;
type AbstractConstructor<T> = Function & { prototype: T };
// type ConstructorFunction = abstract new (...args: any[]) => any;
declare type ConstructorFunction<T extends Utilities> = new (...args: any[]) => T;
type Constructor2<T> = new (...args: any[]) => T

export default function Activatable<TBase extends Constructor2>(Base: TBase) {
    return class extends Base {
        // Mixins may not declare private/protected properties
        // however, you can use ES2020 private fields
        _scale = 111111111111111111111111;
        _isActivated = false;
        _timestamp = Date.now();

        activate() {
            this._isActivated = true;
        }

        deactivate() {
            this._isActivated = false;
        }

        setScale(scale: number) {
            this._scale = scale;
        }

        get scale(): number {
            return this._scale;
        }
    };
}

import Activatable from '@/store/module/abstract/mixin/countdown.ts'

abstract class AbstractModuleForm {...}
abstract class AbstractModuleCountdownForm extends Activatable(AbstractModuleForm)  {...}

class Test extends AbstractModuleCountdownForm {...}

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

Проблема в том, что 2+ абстрактных класса из разных модулей обладают одинаковым набором полей и методов, к примеру createdAt, updatedAt.
Пытаюсь сделать миксин, по документации и ответам на СО все слетает.
Примеры ошибок
  1. Generic type 'Constructor2' requires 1 type argument(s).
  2. Type 'TBase' is not a constructor function type.
  3. Cannot create an instance of an abstract class.
  4. Argument of type 'typeof A' is not assignable to parameter of type 'Constructor<{}>'.
  5. Cannot assign an abstract constructor type to a non-abstract constructor type.
  6. Cannot create an instance of an abstract class.
  7. A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'.
  8. Cannot create an instance of an abstract class.

  9. // это все другие классы что наследуют класс с миксином, все из проперти и методы вырезаются
    TS2339: Property 'setFieldValueByFieldName' does not exist on type 'SecuredModuleFormUpdateAccount'.



Существует ли рабочий способ для абстрактных классво / методов миксина в TS?
Если да, то рабочий пример можно?

TS Playground

Важно подметить, исопльзуется библиотека для vuex class moduels
  • Вопрос задан
  • 49 просмотров
Решения вопроса 1
bingo347
@bingo347 Куратор тега TypeScript
Crazy on performance...
Generic type 'Constructor2' requires 1 type argument(s).

У Вас тип Constructor2 требует дженерик аргумента, а вот тут Вы его используете без дженерика:function Activatable<TBase extends Constructor2>
Можно попробовать так:
function Activatable<T, TBase extends Constructor2<T>>
хотя это сильно зависит от задачи...

Type 'TBase' is not a constructor function type.
эта ошибка вылезла из предыдущей

Cannot create an instance of an abstract class.

Cannot assign an abstract constructor type to a non-abstract constructor type
все правильно ругается, абстрактные классы на то и абстрактные, что в них есть абстрактные методы, у которых реализация должна быть в наследнике, их конструирование приведет к ошибкам и TS от этого защищает.

A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'.
Миксин принимает на вход произвольный абстрактный класс, не зная о всех его абстрактных методах, поэтому он тоже должен быть абстрактным.

type AbstractConstructor<T> = Function & { prototype: T };
Вот этот тип некорректен...
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы