import { AnyClass, Constructor } from './core';
import * as Joi from 'joi';
import 'reflect-metadata';
/**
 * The minimal implementation of Joi required for this module.
 * (Do this for type safety in testing, without needing to mock the whole of Joi.)
 */
declare type JoiForValidator = Pick<typeof Joi, 'object' | 'array'>;
export declare class NoValidationSchemaForClassError extends Error {
    constructor(Class: AnyClass);
}
export declare class MultipleValidationError extends Error {
    readonly errors: Joi.ValidationError[];
    constructor(errors: Joi.ValidationError[]);
}
export interface ValidationResultPass<T> {
    error: null;
    errors: null;
    warning: null;
    value: T;
}
export interface ValidationResultFail<T> {
    error: Joi.ValidationError;
    errors: null;
    warning: null;
    value: T;
}
export declare type ValidationResult<T> = ValidationResultPass<T> | ValidationResultFail<T>;
/**
 * Returns true if validation result passed validation.
 * @param validationResult The validation result to test.
 */
export declare function isValidationPass<T>(validationResult: ValidationResult<T>): validationResult is ValidationResultPass<T>;
/**
 * Returns true if validation result failed validation.
 * @param validationResult The validation result to test.
 */
export declare function isValidationFail<T>(validationResult: ValidationResult<T>): validationResult is ValidationResultFail<T>;
export declare class InvalidValidationTarget extends Error {
    constructor();
}
export interface ValidationOptions extends Joi.ValidationOptions {
    joi?: JoiForValidator;
}
export declare class Validator {
    private defaultOptions?;
    constructor(defaultOptions?: ValidationOptions | undefined);
    /**
     * Issue #117: Joi's `validate()` method dies when we pass it our own validation options, so we need to strip it
     *  out.
     * @url https://github.com/joiful-ts/joiful/issues/117
     */
    protected extractOptions(options: ValidationOptions | undefined): {
        joi: JoiForValidator;
        joiOptions?: Joi.ValidationOptions;
    };
    /**
     * Validates an instance of a decorated class.
     * @param target Instance of decorated class to validate.
     * @param options Optional validation options to use. These override any default options.
     */
    validate: <T extends {} | null | undefined>(target: T, options?: ValidationOptions | undefined) => ValidationResult<T>;
    /**
     * Validates a plain old javascript object against a decorated class.
     * @param target Object to validate.
     * @param clz Decorated class to validate against.
     * @param options Optional validation options to use. These override any default options.
     */
    validateAsClass: <TClass extends Constructor<any>, TInstance = TClass extends Constructor<infer TInstance_1> ? TInstance_1 : never>(target: Partial<TInstance> | null | undefined, Class: TClass, options?: ValidationOptions | undefined) => ValidationResult<TInstance>;
    /**
     * Validates an array of plain old javascript objects against a decorated class.
     * @param target Objects to validate.
     * @param clz Decorated class to validate against.
     * @param options Optional validation options to use. These override any default options.
     */
    validateArrayAsClass: <TClass extends Constructor<any>, TInstance = TClass extends Constructor<infer TInstance_1> ? TInstance_1 : never>(target: Partial<TInstance>[], Class: TClass, options?: ValidationOptions | undefined) => ValidationResult<TInstance[]>;
}
export declare const createValidatePropertyDecorator: (options: {
    validator?: Validator;
} | undefined) => MethodDecorator;
export {};
