Closed
Description
TypeScript Version: 4.0.2
Search Terms: mixins, inheritance
Code
type Mixable = new (...args: any[]) => {};
class Base {
constructor(protected _a: string, protected _b: string) {}
}
const A = (Base: Mixable) => class A extends Base {
a() {
console.log(this._a);
return this;
}
};
const B = (Base: Mixable) => class B extends Base {
b() {
console.log(this._b);
return this;
}
};
const C = A(B(Base));
const o = new C("a","b");
o.a().b();
Expected behavior: The compiler should be able to identify the properties shared among mixins, and should not emit any error.
Actual behavior: TypeScript emit errors that it does not able to identify the shared properties, and also failed to chain methods.
Playground Link: https://bit.ly/34q5ueS
Note: If you run this, it runs successfully, and generates the expected output without any JS error.
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
[-]TypeScript unables to identify the shared properties among mixins[/-][+]TypeScript unable to identify the shared properties among mixins[/+][-]TypeScript unable to identify the shared properties among mixins[/-][+]TypeScript unable to identify the properties shared among mixins[/+]ENvironmentSet commentedon Oct 4, 2020
It seems not a problem of typescript.
_a
or_b
in classA
andB
since only some instance ofBase
(variable that typed asMixable
) would have them. (e.gclass noop {}
is value ofMixable
type.)Base
inA
andB
, typescript would only care the case whenBase
is value ofMixable
. So you must use generic in this case.playground
AnmSaiful commentedon Oct 4, 2020
@ENvironmentSet excellent! So the generic solved the chaining issue. Do you know any workaround to make the properties accessible to A and B?
ENvironmentSet commentedon Oct 5, 2020
All you need just to make
Mixable
type more specific. (i.e. make return type of `Mixable have properties.)P.S. there is some kind of design problem related to private/protected property of exported classes(classes like
A
andB
).AnmSaiful commentedon Oct 7, 2020
Thanks, @ENvironmentSet for your contributions. It added a huge value to the issue.
My primary goal to use mixins is to decompose my large classes. As because this will be applied in different classes, I am creating a helper module. In order to keep the example understandable, I posted a simpler implementation.
So, here's what I've come up with so far keeping extensibility in mind. Please ignore the weird name
Libbable
(this is just to demonstrate the idea).Link to the Playground
Because of the design issue you mentioned, TypeScript is not able to share non-public properties among mixins. I really look forward to being able to use this, otherwise, the powerful access modifiers are simply useless here.
As it is necessary to declare the methods in the Base class to use them in the mixins, they will be gets called once the applicable class methods of the mixins are called. This is not what I want to happen. JS allows us to get rid of this, but TS doesn't. If you have a better idea to achieve what I want, feel free to share.
typescript-bot commentedon Oct 11, 2020
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.