As I work on creating a multi-mixin helper function that takes in a map of constructors and returns an extended map with new interfaces, I come across some challenges.
Let's first look at the basic base classes:
class Alpha { alpha: string = 'alpha'; };
class Beta { beta: string = 'beta'; };
I've developed a mixin helper function that can receive these classes as input and provide enhanced versions based on them. Below is a simplified version without type declarations:
// The multi-mixin helper function:
const Fooable = ({ Alpha, Beta }) => {
const AlphaWithFoo = class extends Alpha {
foo = 'foo';
};
return { Alpha: AlphaWithFoo, Beta };
}
// Usage example:
const { Alpha: FooAlpha, Beta: FooBeta } = Fooable({ Alpha, Beta });
const fooAlpha = new FooAlpha();
// fooAlpha now has both "alpha" and "foo" properties:
console.log(fooAlpha.alpha, fooAlpha.foo);
However, when I introduce proper typings for this function, it leads to a confusing not-assignable error from the TypeScript compiler. You can see my code and the associated error in the TypeScript playground here.
The error message reads:
Type '<A extends Alpha, B extends Beta>({ Alpha, Beta }: Domain<A, B>) => { Alpha: typeof AlphaWithFoo;...' is not assignable to type 'DomainExtender<Foo, {}>'.
Type '{ Alpha: typeof AlphaWithFoo; Beta: Constructor<B>; }' is not assignable to type 'ExtendedDomain<A, B, Foo, {}>'.
Types of property 'Alpha' are incompatible.
Type 'typeof AlphaWithFoo' is not assignable to type 'Constructor<A & Foo>'.
Type 'AlphaWithFoo' is not assignable to type 'A & Foo'.
This error poses a challenge in understanding where the issue lies. It appears like the compiler is having trouble tracking the type information for the Alpha
class. This could be due to a mistake on my end rather than an inherent flaw in the code.
If anyone can assist me in pinpointing the root cause of this problem, I would greatly appreciate it.