import type { IContainer, Tagged } from '../container/IContainer';
import type { MapFn } from '../utils';
import { ProviderPipe } from './ProviderPipe';
export type ProviderResolveOptions = {
    args: unknown[];
    lazy?: boolean;
};
export type ResolveDependency<T = unknown> = (container: IContainer, options: ProviderResolveOptions) => T;
export type ScopeAccessOptions = {
    invocationScope: Tagged;
    providerScope: Tagged;
};
export type ScopeAccessFn = (options: ScopeAccessOptions) => boolean;
export type ArgsFn = (l: IContainer, ...args: unknown[]) => unknown[];
export interface IMapper<T> {
    mapItem<T>(target: IProvider<T>): IProvider<T>;
}
export interface IProvider<T = any> {
    resolve(container: IContainer, options: ProviderResolveOptions): T;
    hasAccess(options: ScopeAccessOptions): boolean;
    pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
    setAccessPredicate(hasAccessWhen: ScopeAccessFn): this;
    setArgs(argsFn: ArgsFn): this;
}
export declare const args: <T>(...extraArgs: unknown[]) => ProviderPipe<T>;
export declare const argsFn: <T>(fn: ArgsFn) => ProviderPipe<T>;
export declare const scopeAccess: <T>(predicate: ScopeAccessFn) => ProviderPipe<T>;
export declare abstract class ProviderDecorator<T> implements IProvider<T> {
    private decorated;
    protected constructor(decorated: IProvider<T>);
    setAccessPredicate(predicate: ScopeAccessFn): this;
    hasAccess(options: ScopeAccessOptions): boolean;
    resolve(container: IContainer, options: ProviderResolveOptions): T;
    pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
    setArgs(argsFn: ArgsFn): this;
}
