type Scope = 'singleton' | 'module';
type Resolver<M extends object, Params extends object, R> = {
    (injection: M, params: Params): R;
    scope?: Scope;
};
type Resolvers<Items extends object, M extends object, Params extends object> = {
    [Item in keyof Items]: Resolver<M, Params, Items[Item]>;
};
type NotOf<T extends object> = Record<PropertyKey, unknown> & {
    [K in keyof T]?: never;
};
type Initializers<M, Params> = {
    [Item in keyof M]?: (this: M[Item], module: Omit<M, Item>, params: Params) => void;
};
type SomeImpl<M extends object> = {
    [key: string]: (self: M, ...args: never[]) => unknown;
};
type MethodsOf<Impl extends SomeImpl<M>, M extends object> = {
    [key in keyof Impl]: Impl[key] extends (self: M, ...args: infer A) => infer R ? (...args: A) => R : never;
};
interface IExtendable<Pr extends object, Pb extends object, Params extends object> {
    private<NPr extends NotOf<Pr & Pb>, NP extends object>(resolvers: Resolvers<NPr, Pr & Pb, NP & Params>, scope?: Scope): ModuleBuilder<{
        [p in keyof (Pr & NPr)]: (Pr & NPr)[p];
    }, Pb, {
        [p in keyof (Params & NP)]: (Params & NP)[p];
    }>;
    public<NPb extends NotOf<Pr & Pb>, NP extends object>(resolvers: Resolvers<NPb, Pr & Pb, NP & Params>, scope?: Scope): ModuleBuilder<Pr, {
        [p in keyof (Pb & NPb)]: (Pb & NPb)[p];
    }, {
        [p in keyof (Params & NP)]: (Params & NP)[p];
    }>;
    privateImpl<Impl extends SomeImpl<Pr & Pb>>(implementation: Impl): ModuleBuilder<{
        [p in keyof (Pr & MethodsOf<Impl, Pr & Pb>)]: (Pr & MethodsOf<Impl, Pr & Pb>)[p];
    }, Pb, Params>;
    publicImpl<Impl extends SomeImpl<Pr & Pb>>(implementation: Impl): ModuleBuilder<Pr, {
        [p in keyof (Pb & MethodsOf<Impl, Pr & Pb>)]: (Pb & MethodsOf<Impl, Pr & Pb>)[p];
    }, Params>;
    init(initializers: Initializers<Pr & Pb, Params>): ICreatable<Pb, Params>;
}
type ICreatable<Pb extends object, Params extends object> = Record<PropertyKey, never> extends Params ? {
    create(): Pb;
} : {
    create(params: Params): Pb;
};
type ModuleBuilder<Pr extends object, Pb extends object, Params extends object> = IExtendable<Pr, Pb, Params> & ICreatable<Pb, Params>;

declare const scope: {
    module: string;
    singleton: string;
};
declare const Module: <Pr extends object = { [key in never]: never; }, Pb extends object = { [key in never]: never; }, Params extends object = { [key in never]: never; }>() => ModuleBuilder<Pr, Pb, Params>;

export { Module, Module as default, scope };
