Created
January 21, 2020 09:24
-
-
Save 46bit/8852ea9d5219228368e1dfd9db4f785e to your computer and use it in GitHub Desktop.
TypeScript's built-in mixins don't allow the mixin to have a useful constructor. I came across https://github.com/Microsoft/TypeScript/issues/14126#issuecomment-503940323 and wanted to check that it really works. It does!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type ComposableConstructor<T, U> = | |
[T, U] extends [new (a: infer O1) => infer R1,new (a: infer O2) => infer R2] ? { | |
new (o: O1 & O2): R1 & R2 | |
} & Pick<T, keyof T> & Pick<U, keyof U> : never | |
function MixA<T extends new (o: any) => any>(Base: T) { | |
class MixA extends (Base as new (...a: any[]) => {}) { | |
a_value: number; | |
constructor(options: { a_value: number }) { | |
super(options) | |
this.a_value = options.a_value; | |
} | |
a() { | |
console.log("a: " + this.a_value) | |
} | |
} | |
return MixA as ComposableConstructor<typeof MixA, T> | |
} | |
function MixB<T extends new (o: any) => any>(Base: T) { | |
class MixB extends (Base as new (...a: any[]) => {}) { | |
b_value: string; | |
constructor(options: { b_value: string }) { | |
super(options) | |
this.b_value = options.b_value; | |
} | |
b() { | |
console.log("b: " + this.b_value) | |
} | |
} | |
return MixB as ComposableConstructor<typeof MixB, T> | |
} | |
class AB extends MixA(MixB(class { })) { | |
ab_value: string; | |
constructor(options: { a_value: number, b_value: string, ab_value: string }) { | |
super(options) | |
this.ab_value = options.ab_value; | |
} | |
ab() { | |
console.log("ab: " + this.ab_value) | |
} | |
} | |
function main() { | |
let ab = new AB({ a_value: 77, b_value: "wow", ab_value: "wowwww" }); | |
ab.a(); | |
ab.b(); | |
ab.ab() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment