ts-mixer: Mixin Parent Class does not receive Child Class's "this".
When using regular heritance:
class Parent{
constructor() {
console.log('Parent name:'+ this.constructor.name)
}
}
class Child extends Parent{
constructor() {
super()
console.log('Child name:'+ this.constructor.name)
}
}
let child = new Child();
Outputs:
Parent name:Child
Child name:Child
But when I use Mixin from ts-mixer:
import { Mixin } from 'ts-mixer';
class Parent {
constructor() {
console.log('Parent name:' + this.constructor.name);
}
}
class Child extends Mixin(Parent) {
constructor() {
super();
console.log('Child name:' + this.constructor.name);
}
}
const child = new Child();
Outputs:
Parent name:Parent
Child name:Child
So it’s not getting the correct “this”
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 17 (8 by maintainers)
Commits related to this issue
- test: adds test that demonstrates issue raised in #20 — committed to tannerntannern/ts-mixer by tannerntannern 4 years ago
Hi @Judahh, thanks for your patience. I’ve started working on this but I haven’t gotten a chance to push anything out to npm yet. I’m hoping to get more time this evening. I will post a link here when I have a beta version ready to go!
As soon as fixed, please post a beta version. Thanks
Yes, waiting for it. Thanks.
Thanks for your patience everyone. The beta release is available. You will have to use
npm install ts-mixer@5.2.0-beta.0in order to get the beta rather than 5.1.0. I’ve also added a section in the docs explaining a bit more about the feature.Please let me know what you think! If there are no issues, I’ll promote it to an actual release in a few days.
Hi all, once again let me know if you run into any issues. If not I’ll promote it to a full release in a few days!
Another problem is that is not possible to override the init method
One question, is there a beta version for this release or is not so simple to implement?
Hi @Judahh, I probably should have made this more explicit in the caveats section of the README, but this is expected behavior. Unfortunately, ES6 makes it impossible to call constructors as regular functions, which is necessary to get the “correct” behavior.
Something I’ve considered previously (but haven’t seen the demand for it until now) is adding a configuration option to
ts-mixerthat causes it to automatically call a designated init function, which can be called with the properthis. I was thinking it would look something like this:Obviously, this is pretty clunky, but I’ve spent many hours wrestling with this problem and I don’t think there’s another way around it, aside from keeping your constructors pure.
Is this be a feature you’d be interested in?
v5.2.0-beta.1 is now available. I believe this fixes the issue you raised @Judahh. The bug was related to mixing classes that were already mixed by
ts-mixer. This is something the library should be able to handle just fine (now that the bug is fixed), but it is a bit of an anti-pattern.To illustrate, this is a similar hierarchy to what you posted in your test snippet:
But
ts-mixercan mix more than two classes at a time, so you may find it better to skip the intermediateEclass and do this instead:Of course, you may have had a good reason for using the intermediate
Eclass, but I just wanted to point out the possibility.Thanks for catching. I will try to look into this later tonight. If you could provide a minimal code snippet that reproduces the issue, it will help me incorporate it into my test suite faster. 👍
Sort of, but it probably won’t help you here. Previous versions of
ts-mixerused to behave differently depending on whether your compile target was set toes5ores6. The reason for this was that TypeScript transforms class expressions into the older function style when targeting pre-ES6. For example:Unlike ES6 classes, this older style can be used for calling constructors without
new. Sots-mixerwould detect this and applythisthe “correct” way for these old style classes. However, having split behavior for different compile targets didn’t seem like a good idea to me, especially now that ES6 is 5 years old and fewer and fewer people are going to be targeting pre-ES6. So this behavior was removed.Looks like when you have more than 3 levels of heritance ‘this’ starts to stop working
I need this too. Waiting for release of this beta version! @tannerntannern