composer.ts (904B)
1 export class RegistryComposer<TNeeds extends object = object> { 2 private readonly creators: CreateServices<TNeeds, object>[] = []; 3 4 add<TServices extends object>( 5 createServices: CreateServices<TNeeds, TServices>, 6 ): RegistryComposer<Combine<TNeeds, TServices>> { 7 this.creators.push(createServices); 8 return this as never as RegistryComposer<Combine<TNeeds, TServices>>; 9 } 10 11 compose(): Readonly<TNeeds> { 12 return Object.freeze( 13 this.creators.reduce((state, createServices) => { 14 return Object.assign(state, createServices(state)); 15 }, {} as TNeeds), 16 ); 17 } 18 } 19 20 export type CreateServices<TNeeds, TServices extends object = object> = ( 21 needs: TNeeds, 22 ) => TServices; 23 24 type Combine<TSource extends object, TWith extends object> = Norm< 25 Omit<TSource, keyof TWith> & TWith 26 >; 27 28 export type Norm<T> = T extends object ? { 29 [P in keyof T]: T[P]; 30 } 31 : never;