-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't extend intersection containing constructable type parameter #22824
Comments
This form does not work either: export const Mixin4 = <T extends Constructable>(base : T) => {
class Temp extends Mixin1<Constructable>(base) {
methodTemp () {
this.method1() // typechecks fine
}
}
return class Mixin4 extends Mixin3(Temp) {
method4 () {
this.method1() // !!! not found
this.method2()
}
}
} |
Huh, but changing the order of mixin applications fixes it: export const Mixin4 = <T extends Constructable>(base : T) =>
// class Mixin4 extends Mixin3(Mixin1(base)) { -- fails in this order
class Mixin4 extends Mixin1(Mixin3(base)) { // -- works in this order
method4 () {
this.method1() // method found
this.method2() // method found
}
} Ehm, why does the order of mixins application matter in this case? Definitely feels like some quirk in the typechecker. |
The bug is that we don't consider an intersection containing a constructable type parameter to be constructable: type Ctr = new (...args : any[]) => any;
const Mixin1 = <T extends Ctr>(Sup: T) => class extends Sup {};
const Mixin2 = <T extends Ctr>(Sup: T) => class extends Mixin1(Sup) {}; |
Cool, hopefully the fix will make it to 2.8.0 final.. |
Any workarounds possible to use right now? |
It doesn't look like there's a good workaround, besides avoiding mixins extending mixins and having the final ("leaf") class declarations directly write all the mixins they want to include. |
I see. In our project we primarily use mixins for functionality extension (a-la haskell typeclasses). There's not many "leaf" class declarations actually - those are in the external project, that consumes required parts of the functionality from ours. |
Some thoughts: The test case you posted: type Ctr = new (...args : any[]) => any;
const Mixin1 = <T extends Ctr>(Sup1: T) => class extends Sup1 {};
const Mixin2 = <T extends Ctr>(Sup2: T) => class extends Mixin1(Sup2) {}; Can be fixed with explicit type for the application of generic function type Ctr = new (...args : any[]) => any;
const Mixin1 = <T1 extends Ctr>(Sup1: T1) => class extends Sup1 {};
const Mixin2 = <T2 extends Ctr>(Sup2: T2) => class extends Mixin1<Ctr>(Sup2) {}; Shouldn't that be a job of type inference facilities? Since So the bug is probably in the code for type inference for generic functions. |
|
Right |
Lets say we have 2 mixins, like this:
Now we want to declare a
Mixin3
that already includesMixin2
:but this form will work
This is generally fine.
Now, we want to declare
Mixin4
which includesMixin3
andMixin1
:Note, that for
Mixin4
the specification of the formMixin2<Constructable>
like we did forMixin3
is not needed.It seems the nested application of the
Mixin1
in the declaration ofMixin4
was not "picked up". Any help is greatly appreciated.=======================================================================
All the code from above in one snippet:
The text was updated successfully, but these errors were encountered: