import { Injectable, Injected } from 'metaf-resolvable';
import { ReactNode } from 'react';
export declare type HOC = (app: ReactNode) => JSX.Element;
/**
 * @description requirements for host application
 */
export declare type IRequirements = HOC[];
declare const requirementsOverride: unique symbol;
/**
 * Interface that forces users to make type safe overrides
 * @description requirements override
 * @template T type of dependency that have to be overwritten
 * @template R
 */
export interface IRequirementsOverride<T extends HOC = HOC, R extends T = T> {
    [requirementsOverride]: [T, R];
}
/**
 * Function that meant to be used as only way for specifying requirements overrides
 * it's designed to provide best possible type safety, but until something like this:
 * https://github.com/Microsoft/TypeScript/issues/13890
 * will land to TSX type inference, it only forces users to replace requirement HOC
 * by another HOC, which, obviously, could ignore initial invariants,
 * but unfortunately there are no better options for now
 * @description creates a `[key, value]` pair describing requirement override
 * @template T type of requirement key that has to be overwritten
 * @template R type of value that will be used instead of original requirement
 * @param key actual key that has to be overwritten
 * @param value value that will be passed as requirement for this `key`
 * @returns object with symbol property which point to `[key, value]` pair
 */
export declare function overrideRequirement<T extends HOC, R extends T>(key: T, value: R): IRequirementsOverride<T, R>;
/**
 * Entry point for resolving requirements for particular `ResolvableComponent`,
 * but also could be used as a HOC for any other component including `SFC`s
 * @description resolves `requirements` for `componentImpl` and applies them to `ApplicationRoot`
 * @template R type of `requirements` tuple
 * @template C type of `componentImpl`
 * @param requirements tuple of specific requirements that should be met by hosting application
 * @param componentImpl particular resolvable class implementation
 * @returns exactly same `componentImpl`, but with resolved requirements
 */
export declare function resolveRequirements<R extends IRequirements = [], C extends object = {}>(requirements: R, componentImpl: C): C;
export declare type IOverridesHelper = {
    set<T extends Injectable = Injectable>(key: T, value: Injected<T>): IOverridesHelper;
};
export declare const overrides: IOverridesHelper;
export {};
//# sourceMappingURL=Resolver.d.ts.map