Created
March 23, 2026 09:27
-
-
Save nopeless/9d29c657695fe859094aa0d84165851c to your computer and use it in GitHub Desktop.
interesting ts pattern i tried
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
| class Car { | |
| constructor( | |
| public make: string, | |
| public model: string, | |
| ) {} | |
| } | |
| const gasParent = { | |
| gas: 0, | |
| }; | |
| const refuelParent = { | |
| refuel(this: Car & { gas: number }, amount: number) { | |
| this.gas += amount; | |
| console.log(`Refueled ${amount} units of gas for ${this.model}. Total gas: ${this.gas}`); | |
| }, | |
| }; | |
| type Composers<This, Arr extends readonly unknown[]> = Arr extends readonly [ | |
| infer First, | |
| ...infer Rest, | |
| ] | |
| ? [ | |
| { | |
| [K in keyof First]: First[K] extends (...args: infer As) => infer R | |
| ? (this: This & First, ...args: As) => R | |
| : First[K]; | |
| }, | |
| ...Composers<This & First, Rest>, | |
| ] | |
| : Arr; | |
| type Composed<Arr extends readonly unknown[], Acc> = Arr extends readonly [ | |
| infer First, | |
| ...infer Rest, | |
| ] | |
| ? Composed<Rest, Acc & First> | |
| : Acc; | |
| function Compose<Args extends unknown[], T extends {}, Parents extends readonly unknown[]>( | |
| base: new (...args: Args) => T, | |
| parents: Composers<T, Parents>, | |
| ) { | |
| const clazz = class extends base {}; | |
| for (const parent of parents) { | |
| Object.assign(clazz.prototype, parent); | |
| } | |
| return clazz as new (...args: Args) => T & Composed<Parents, {}>; | |
| } | |
| const ComposedCar = Compose(Car, [gasParent, refuelParent]); | |
| const myCar = new ComposedCar("toyota", "corolla"); | |
| myCar.refuel(10); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment