Home:ALL Converter>What is the type of mixin functions?

What is the type of mixin functions?

Ask Time:2021-10-27T18:20:35         Author:S. Wolf

Json Formatter

I have a rough idea of what the type of mixin functions should be, but I keep getting errors no matter how I approach it. For example, this code works:

class BaseClass {}
type Constructor<T extends BaseClass> = new (...args: any[]) => T;
type Mixin = <T extends BaseClass, U extends T>(Base: Constructor<T>) => Constructor<U>;

const mixins: Array<Mixin> = [];

class Mixer {
    private static mixins: Record<string, Mixin> = {};

    public static registerMixin(name: string, mixin: Mixin): void {
        if (!Mixer.mixins[name]) {
            Mixer.mixins[name] = mixin;
        }
    }

    public static getClass(...mixinNames: Array<string>): Constructor<BaseClass> {
        let mixedClass = BaseClass;

        for (const name of mixinNames) {
            if (Mixer.mixins[name]) {
                mixedClass = Mixer.mixins[name](mixedClass);
            }
        }

        return mixedClass;
    }
}

Mixer.registerMixin('a', Base => class extends Base { public a = '' });
Mixer.registerMixin('b', Base => class extends Base { public b = '' });
Mixer.registerMixin('c', Base => class extends Base { public c = '' });
Mixer.registerMixin('d', Base => class extends Base { public d = '' });
Mixer.registerMixin('e', Base => class extends Base { public e = '' });

console.log(new (Mixer.getClass('a', 'c', 'e'))());

If you copy it to the typescript playground (https://www.typescriptlang.org/play), for example, you will see that the code behaves as you'd expect it to. For each of the Mixer.registerMixin calls, though, you get these two errors:

Type 'typeof (Anonymous class)' is not assignable to type 'Constructor<U>'.
  Type '(Anonymous class)' is not assignable to type 'U'.
    '(Anonymous class)' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'BaseClass'.

Class '(Anonymous class)' incorrectly extends base class 'T'.
  '(Anonymous class)' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'BaseClass'.

At this point, I am uncertain whether my Mixin type is wrong or whether I need to add annotations somewhere in the Base => class extends Base { /* ... */ } constructs. Does anybody know how to get rid of the errors?

Author:S. Wolf,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/69736873/what-is-the-type-of-mixin-functions
yy