-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
π Search Terms
Mixin mixins 20 21 type instantiation is excessively deep and possibly infinite
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
β― Playground Link
π» Code
abstract class BaseObj {
constructor(...args: any[]) {}
}
function Trait0F<TBase extends typeof BaseObj>(Base: TBase){
abstract class Trait0 extends Base {}
return Trait0
}
function Trait1F<TBase extends typeof BaseObj>(Base: TBase){
abstract class Trait1 extends Base {}
return Trait1
}
// ...
function Trait21F<TBase extends typeof BaseObj>(Base: TBase){
abstract class Trait21 extends Base {}
return Trait21
}
const ConcreteBase = Trait21F(Trait20F(Trait19F(Trait18F(Trait17F(Trait16F(Trait15F(Trait14F(Trait13F(Trait12F(Trait11F(Trait10F(Trait9F(Trait8F(Trait7F(Trait6F(Trait5F(Trait4F(Trait3F(Trait2F(Trait1F(Trait0F(BaseObj)))))))))))))))))))))); // excessively deep
class ConcreteChild extends ConcreteBase {}π Actual behavior
The line with Trait21F(...) where we assign to ConcreteBase throws the "type instantiation is excessively deep" error. The error goes away if there is at most 20 mixins (e.g. the last one is Trait19F), so any number more than 20 seems to be the problem.
It's worth noting that if for every trait we had a static class e.g. class Trait0 extends Trait0F(BaseObj) and then intersected them all together, e.g. const ConcreteBase = typeof Trait21 & ... & typeof Trait0 & typeof BaseObj that everything works (TS playground), which feels like it should be functionally equivalent.
Expressing this the manual way, by having the equivalent trait classes extend each other statically (class Trait1 extends Trait0 etc...), also works: TS Playground
π Expected behavior
I would expect this to not error. This recursion isn't infinite and doesn't seem like it would exceed the depth limit of 100 currently hard-coded into the compiler, and in general the 2 alternatives which work should be equivalent.