TS Playground - An online editor for exp...

Here's a different version in a playground link Honestly I started with a simpler model of "what a mixin is" because I knew that it'd probably actually decrease in readability rapidly, and indeed it did.
TS Playground - An online editor for exploring TypeScript and JavaS...
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
3 Replies
Eunomiac
Eunomiac•16mo ago
Hello again! I was wondering if you could help me a bit more with the awesome MixIns TypeScript code you kindly fixed up for me? I'm having a problem when I want to write a mixin that "knows" it will be applied to, say, a subclass of Actor, so I can include methods in the mixin that refer to Actor methods and properties --- e.g. I want to be able to write, say, this.items inside the mixin. Doing so currently throws a "Parameter 'item' implicitly has an 'any' type", because the mixin doesn't know it will be descending from an Actor subclass. Would a generic version of your Constructor type help? I tried replacing Constructor with this type:
type ConstructorOf<T> = new (...args: readonly any[]) => T
type ConstructorOf<T> = new (...args: readonly any[]) => T
... and then defining the mixin as:
export const PlayableCharacterMixin = (superclass: ConstructorOf<Actor>) => class extends superclass {
/* ... */
}
export const PlayableCharacterMixin = (superclass: ConstructorOf<Actor>) => class extends superclass {
/* ... */
}
... which removes the 'implicit any' errors. However, when I try to apply it to a subclass of Actor, e.g.:
class BladesPC extends MIX(Actor).with(PlayableCharacterMixin) {
/* ... */
}
class BladesPC extends MIX(Actor).with(PlayableCharacterMixin) {
/* ... */
}
... the methods within BladesPC no longer recognize that they descend from a subclass of Actor and PlayableCharacterMixin (i.e. 'override' keywords throw errors, as does this.items and similar Actor-dependent code). I've created a playground link where you can see the error in the RenderMixin on line 57. I know you've already helped me so much, but I'd really love to get this working --- as I just discovered how to make multiple Actor/Item subclasses via Proxy objects and polymorphism, and mixins will make that sing 😄 ... ah, one other issue that might be related, or might be another tricky TypeScript hurdle to overcome: I have defined several interfaces that dictate the structure of my subclasses. But a class definition like so:
class BladesPC extends MIX(BladesActor).with(PlayableCharacterMixin) implements BladesActorInterface.PlayableCharacter {
/* ... */
}
class BladesPC extends MIX(BladesActor).with(PlayableCharacterMixin) implements BladesActorInterface.PlayableCharacter {
/* ... */
}
... throws an error saying BladesPC doesn't properly implement BladesActorInterface.PlayableCharacter because it is missing all of the methods contained within the PlayableCharacterMixin (i.e. TypeScript doesn't recognize at this point that BladesPC includes all of the methods in PlayableCharacterMixin).
LukeAbby
LukeAbbyOP•16mo ago
export const RenderMixin = <T extends ConstructorOf<BladesActor>|ConstructorOf<BladesItem>>(superclass: T) => class extends superclass { Should be export const RenderMixin = <T extends ConstructorOf<BladesActor>&ConstructorOf<BladesItem>>(superclass: T) => class extends superclass { The issue at hand is basically that superclass has to be a concrete class. This means that it concretely has to have a list of methods. Currently you're dictating that it can have methods from Actor OR Item. That sounds like it makes sense, right? But what would happen if you did override itemSpecificMethod? Or override actorSpecificMethod? So you really want superclass to be based upon what's in COMMON between Actor AND Item
Eunomiac
Eunomiac•16mo ago
Of course! For some reason, I always get mixed up in the logic between unions and intersections in typescript. Thanks again!
Want results from more Discord servers?
Add your server