ARTICLE AD BOX
I'm following the example in TypeScript's mixin documentation, which promises me that:
With these all set up, then you can create a class which represents the base class with mixins applied:
class Sprite {...} function Scale<TBase extends new (...args: any[]) => {}>(Base: TBase){...} // Compose a new class from the Sprite class, // with the Mixin Scale applier: const EightBitSprite = Scale(Sprite);Except, I'm finding that EightBitSprite is actually a value rather than a class i.e:
const mapOfSprites = new Map<string, Sprite>(); //Works //TS2749: EightBitSprite refers to a value, but is being used as a type here. Did you mean typeof EightBitSprite? const mapOfEightBitSprites = new Map<string, EightBitSprite>();The annoying thing about this is that:
Everywhere in my code, when using a class's type, I need to remember if it's a real class or a mixed class.
If I change a class declaration to a mixed class, then I need to update all the places I use its type. E.g., if I change class ScalableTextBox {...pre-mixin-impl...} → const ScalableTextBox = Scale(TextBox) then I need to go update all function(): ScalableTextBox {...} to function(): typeof ScalableTextBox {...} and so on.
The only workaround I've found so far is to define a third class that extends the result of mixing the base class, i.e.
//Works class RealEightBitSprite extends EightBitSprite {} const mapOfRealEightBitSprites = new Map<string, RealEightBitSprite>();This is OK. It solves problem #2 (E.g. class ScalableTextBox {...} → class ScalableTextBox extends Scale(OldScalableTextBox){}. However:
It feels clunky / inelegant to me. Maybe because it results in a rather convoluted calss hierarchy: RealEightBitSprite extends EightBitSprite extends Scaling extends Sprite
More importantly, problem #1 has gotten worse. I now have two different 'classes', RealEightBitSprite and EightBitSprite that are functionaly identical, and so are easy to mix up. The only noticable diference between them is that RealEightBitSprite is both a type and a value, whereas EightBitSprite is a value only.
Is there a way to make it so that EightBitSprite is both a value and a type? The documentation for Declaration Merging implied that there isn't, and sent me back to Mixins, so I suspect that there just isn't a solution.
