TypeScript
TypeScript copied to clipboard
Mixins not working as expected for generic types
🔎 Search Terms
Combinations of mixin generic type lost unknown
🕗 Version & Regression Information
TS 4.8.2
⏯ Playground Link
https://www.typescriptlang.org/play?#code/MYGwhgzhAEDiCmA7eAnAlsAsgewCbxAB4AVAPmgG8AoaW6ANzBAFd4B+ALmmIG4qBfKlVCQYAYWwBbAA7ZkiAC4AhSPBLlqdaJLwFOcJKgw58RMn0HDwUaJgCeEmXKQLo8AB4KkucVNnzlVUIIBXREAHMNGjpcbAAKAEpKaK1aAHo092g0GDADZHQsXSIQsMiU1OA5EOgsgF5oBQALHIA6HVM+LUFLD1kUVwU7aXhoAEEAI1KwYAUJRFLmWewUEmgG7AmAK3hZ8gawKdCZ12QAd2g41uuwFHCILjBEOwBtAF0kuvJeIT6V1wAZsxELM0HJoBA0DIQPBMGh3GhECQADTcRz+FxuTzeGCTaazeaLZardHORQqCBqMikUhxCnwLjEUkBJKaOiHfGuEQ2ADKUOkMLhCMQWK8iB80HpyVSdEk8PguES0pllWqrnqjRaEHaxS6KsE3SEWhQ8AUzBQIr50Nh8MRFiE3JgQoVzMxHjFEsh1qFiLirvJQVKiMirIqsSVbJlGSyOWgeQQBWMxUIwIA1ohsGdEOQAGT5IxFUzBULB8hNVDwACEFS0VQW6vWmraHQIetoPV+7n6gOBoPB4UMhR9SLIEYqJrNFugQJBCjBIq9AptwpI-tc7px4yOKBOhNCSwUK0Ia-p6hpdNUjLXoZVce3J2gjugVqXw9Fm6lkdv2nlipv35lOsag1Zpm11Gt9Qg9sjRVCdzUtflBVtRA22gDsrFEWxfwAVWkNd33FGAB0TLBkOLMpaQSP0-DJQJKXI0t-1ocMmNSDIVGAVNshFZpRiDCIAFoJmYSFkBscsTVaSVmFcM4mjsCFsEfPwQAwMAvFwNgoOU+takbUDtRbEBUJ6IA
💻 Code
class GenericModel<T> {
value?: T;
}
class ComponentBase<T> {
model?: GenericModel<T>;
}
class MyComponent extends ComponentBase<string> {
do() {
//Using my ComponentBase model.value is of type 'string' - as expected
const x = this.model;
}
}
export type AbstractConstructor<T = object> = abstract new (...args: any[]) => T;
export function simpleMixin<T, TComponent extends AbstractConstructor<ComponentBase<T>>>(Base: TComponent) {
abstract class SimpleMixin extends Base {
mixed() {
const x = this.model;
}
}
return SimpleMixin;
}
class MixedComponent extends simpleMixin(ComponentBase<string>) {
do() {
//Using this 'simpleMixin' ComponentBase model.value is of type 'string & unknown'! Why is unknown getting mixed in here? TypeScript could / should know, that it is of type string only!
const x = this.model;
}
}
export function genericMixin<T>() {
return function simpleMixin<TComponent extends AbstractConstructor<ComponentBase<T>>>(Base: TComponent) {
abstract class SimpleMixin extends Base {
mixed() {
const x = this.model;
}
}
return SimpleMixin;
}
}
class MixedUpComponent extends genericMixin<string>()(ComponentBase<string>) {
do() {
//Using this 'genericMixin' ComponentBase model.value is of type 'string' again. But the mixin looks pretty complicated (and needs to be applied pretty unintuitive). But it seams to be the only solution right now, since 'simpleMixin' isn't working for some reason.
const x = this.model;
}
}
🙁 Actual behavior
As you can see in the commented lines, the type information is somehow lost / mixed up with unknown.
🙂 Expected behavior
Keep my generic type information
Please give concrete expected / actual behaviors. I can't know what you expect to happen, or why, based on these descriptions.
@RyanCavanaugh have you checked the playground link? I reduced the code to the four lines showing my problem. Now I put in the whole code and added some more comments.
Keeping the generic Type with the mixin is pretty complicated right now.
This issue has been marked as 'Unactionable' and has seen no recent activity. It has been automatically closed for house-keeping purposes.