You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature request: Support for using mixins inside other mixins. #32004
Ryan Cavanaugh (@RyanCavanaugh) I've been working away the problems using Constructor helpers with explicit as unknown as Constructor<Instance> & Static casts, using Constructor.
Here's an example that shows the use of a custom Constructor helper to work around the problems:
typeConstructor<T=object,Aextendsany[]=any[],Static={}>=(new(
...a: A)=>T)&Static;functionConstructor<T=object,Static={}>(Ctor: Constructor<any>): Constructor<T>&Static{returnCtorasany;// we're confident about this any cast.}typeMixinResult<TClassextendsConstructor,TBaseextendsConstructor>=Constructor<InstanceType<TClass>&InstanceType<TBase>>&TClass&TBase;classBaseClass{foo!: string;staticbar=123;}constbase=newBaseClass();base.bar;// correctly not available hereclassTestextendsBaseClass{staticbat="bob";notStatic=4;}functionfactory<TextendsConstructor<BaseClass>>(cls: T){classFactoryResultextendsConstructor<BaseClass,typeofBaseClass>(cls){bar!: string;make(): InstanceType<typeofBaseClass>{returnthis;}}returnFactoryResultasMixinResult<typeofFactoryResult,T>;}constfactoryResult=factory(Test);factoryResult.bat;// good, available herefactoryResult.foo;// good, foo is not a static propertyfactoryResult.bar=42;// good, bar is staticfactoryResult.bar="blah";// good, static bar is not a stringconstfoo=newfactoryResult();foo.notStatic;// good, available herefoo.foo;// good, correctly availablefoo.bar="blah";// good, instance property bar is defined on line 24.foo.bar=42;// good, instance prop bar is not a numberfunctionfactoryG<CextendstypeofBaseClass>(cls: C){returnclassextendsConstructor<BaseClass>(cls){foo=123;// good, we get an errorbar!: string;};}
The class inside the mixin can not properly extend the base class, and it seems we need a type cast to make it work (hence the Constructor helper for that).
The return type needs to capture the type of the constructor that was passed in (the T in factory generic params)
Oh, right, so back to the main point in the OP: The pattern I just illustrated now makes it possible to compose mixins out of other mixins in an understandable way through use of the Constructor helper:
Activity
trusktr commentedon Jul 23, 2019
Ryan Cavanaugh (@RyanCavanaugh) I've been working away the problems using
Constructorhelpers with explicitas unknown as Constructor<Instance> & Staticcasts, usingConstructor.Here's an example that shows the use of a custom
Constructorhelper to work around the problems:playground
The example shows:
Constructorhelper for that).Tin factory generic params)trusktr commentedon Jul 23, 2019
I updated the above example, to show the full pattern I use (needed?) to have proper mixin classes.
trusktr commentedon Jul 23, 2019
Oh, right, so back to the main point in the OP: The pattern I just illustrated now makes it possible to compose mixins out of other mixins in an understandable way through use of the
Constructorhelper:playground
So, to point out the main issue of the OP again, one would think it would be sufficient to write:
but that results in the error
playground
which makes all code that uses
AnotherMixinto break.We know
Baseis aConstructor, and we're telling TypeScript that it is, by forcefully casting it.Would it be possible for TypeScript to just know?
trusktr commentedon Dec 28, 2019
Closing as duplicate of #32080