UNPKG

@katis/weave

Version:

Simple functional dependency injection

36 lines (33 loc) 2.57 kB
type Providers = Record<string, Provider>; type Resolved<D extends Providers> = { [P in keyof D]: ProviderReturn<D[P]>; }; type FnProvider<D, R> = (deps: D) => R; type ProviderReturn<P extends Provider> = P extends ClassProvider<any, infer R> ? R : P extends FnProvider<any, infer R> ? R : never; type ProviderParam<P extends Provider> = P extends ClassProvider<infer D, any> ? D : P extends FnProvider<infer D, any> ? D : never; type ClassProvider<D, R> = HasClassProvider & { new (deps: D): R; }; type HasClassProvider = { readonly isClassProvider: true; }; type Provider<D = any, R = any> = FnProvider<D, R> | ClassProvider<D, R>; /** * Mixin that allows a class to be used as a Provider with `weave`, * takes a base class parameter that the returned class will inherit from */ declare function Provider<B extends new (...args: any[]) => any>(Base: B): B & HasClassProvider; /** Mixin that allows a class to be used as a Provider with `weave` */ declare function Provider(): (new () => object) & HasClassProvider; type AllProviderDependencies<D extends Record<string, Provider>> = UnionToIntersection<{ [P in keyof D]: ProviderDependencies<D[P]>; }[keyof D]>; type ProviderDependencies<F> = F extends () => any ? {} : F extends new () => any ? {} : F extends (arg: infer A) => any ? A : F extends new (arg: infer A) => any ? A : never; type UnionToIntersection<Union> = (Union extends any ? (u: Union) => void : never) extends (i: infer Intersection) => void ? Intersection : never; declare const weave: <P_1 extends _InternalProviders & { [K in keyof UnionToIntersection<{ [P in keyof _InternalProviders]: ProviderDependencies<_InternalProviders[P]>; }[keyof _InternalProviders]>]: FullyResolvedProvider<_InternalProviders, K>; }, _InternalProviders extends Providers = P_1>(providers: P_1) => Resolved<P_1>; type FullyResolved<D extends Providers> = { [K in keyof AllProviderDependencies<D>]: (arg: any) => AllProviderDependencies<D>[K]; }; type FullyResolvedProvider<P extends Providers, K extends keyof AllProviderDependencies<P>> = K extends keyof P ? P[K] extends ClassProvider<any, any> ? new (...arg: ProviderParams<P, K>) => AllProviderDependencies<P>[K] : (...arg: ProviderParams<P, K>) => AllProviderDependencies<P>[K] : never; type ProviderParams<P extends Providers, K> = K extends keyof P ? [deps: ProviderParam<P[K]>] : [deps: unknown]; export { type AllProviderDependencies, type ClassProvider, type FnProvider, type FullyResolved, Provider, type ProviderDependencies, type ProviderParams, type Providers, type Resolved, weave };