import { Awaitable, Empty, Prettify } from '../types'; import { AppContextCore } from './app-context'; type CurAndReq = { [K in keyof Cur | keyof Req]: K extends keyof Cur ? Cur[K] : K extends keyof Req ? Req[K] : never; }; export type AppContext = AppContextCore & CurAndReq; export type AppContextState = A extends AppContext ? CurAndReq : never; export type AppServiceClass = new (ctx: AppContext>, ...args: A) => R; export type AppServiceConfig = C extends new (first: any, ...args: infer A) => any ? A : never; export type AppProvideOptions, P extends string, M extends (keyof InstanceType)[]> = { provide?: P; merge?: M; useValue?: Awaitable>; useFactory?: (ctx: AppContext, ...args: ConstructorParameters) => Awaitable>; useClass?: new (...args: ConstructorParameters) => InstanceType; }; export type AppProvideArgs, P extends string, M extends (keyof InstanceType)[]> = [ ...args: AppServiceConfig, options?: AppProvideOptions ]; type CurResolved = Prettify; type ResolveReq = { [K in keyof Req as K extends keyof Provided ? Provided[K] extends Req[K] ? never : K : K]: Req[K]; }; type ReqResolved = Prettify>; type AppContextResolved = AppContext, ReqResolved>; export type AppProvidedMerged, P extends string, M extends (keyof InstanceType)[]> = AppContextResolved[K]; } & (P extends '' ? Empty : { [K in P]: InstanceType; }), Empty>; export type AppContextUsed[]> = Ctxes extends [] ? AppContext : Ctxes extends [infer First, ...infer Rest extends AppContext[]] ? First extends AppContext ? AppContextUsed, ReqResolved, Rest> : never : never; export {};