import type { CreateScopeOptions, DependencyKey, IContainer, Instance } from './container/IContainer';
import type { constructor } from './utils';
import type { DepKey } from './DepKey';
import type { IInjectFnResolver } from './injector/IInjector';
export type InstancePredicate = (dep: unknown) => boolean;
export type InjectOptions = {
    lazy: boolean;
    args: unknown[];
};
export type ArgsFn = (l: IContainer) => unknown[];
export declare class InjectionResolver<T> {
    private resolveByOptions;
    private isLazy;
    private getArgs;
    constructor(resolveByOptions: (s: IContainer, options: InjectOptions) => T);
    args(...deps: unknown[]): this;
    argsFn(fn: ArgsFn): this;
    lazy(): this;
    resolve(s: IContainer): T;
}
export declare class InstancesResolver implements IInjectFnResolver<Instance[]> {
    private predicate;
    private isCascade;
    constructor(predicate: InstancePredicate);
    cascade(isTrue: boolean): this;
    resolve(c: IContainer): Instance[];
}
export declare const by: {
    many: <T>(target: DependencyKey | DepKey<T>) => InjectionResolver<T[]>;
    one: <T>(target: DependencyKey | constructor<T> | DepKey<T>) => InjectionResolver<T>;
    /**
     * Use it only for optimization. Otherwise, recommended to use `by.one`
     */
    aliasOne: <T>(target: DependencyKey | DepKey<T>) => InjectionResolver<T>;
    instances: (predicate?: InstancePredicate) => InstancesResolver;
    scope: {
        current: (container: IContainer) => IContainer;
        create: (options: CreateScopeOptions) => (l: IContainer) => IContainer;
    };
};
