import type { ImmutableArray, PossibleArray } from "./array.js";
import type { Data } from "./data.js";
import type { ImmutableDictionary, PossibleDictionary } from "./dictionary.js";
import type { AnyCaller } from "./function.js";
/** Object that can validate an unknown value with its `validate()` method. */
export interface Validator<T> {
    /**
     * `validate()` method accepts an unsafe value and returns a valid value.
     *
     * @param unsafeValue A potentially invalid value.
     *
     * @return Valid value.
     *
     * @throws `Error` If the value is invalid and cannot be fixed.
     * @throws `string` If the value is invalid and cannot be fixed and we want to explain why to an end user.
     */
    validate(unsafeValue: unknown): T;
}
/** Extract the type from a validator. */
export type ValidatorType<X> = X extends Validator<infer Y> ? Y : never;
/** A set of named validators in `{ name: Validator }` format. */
export type Validators<T extends Data = Data> = {
    readonly [K in keyof T]: Validator<T[K]>;
};
/** Extract the type from a set of validators. */
export type ValidatorsType<T> = {
    readonly [K in keyof T]: ValidatorType<T[K]>;
};
/** Require a valid value for a given validator, or return `undefined` if the value could not be validated. */
export declare function getValid<T>(value: unknown, validator: Validator<T>): T | undefined;
/** Require a valid value for a given validator, or throw `RequiredError` if the value could not be validated. */
export declare function requireValid<T>(value: unknown, validator: Validator<T>, caller?: AnyCaller): T;
/**
 * Validate an iterable set of items with a validator.
 *
 * @yield Valid items.
 * @throw string if one or more items did not validate.
 */
export declare function validateItems<T>(unsafeItems: PossibleArray<unknown>, validator: Validator<T>): Iterable<T>;
/**
 * Validate an array of items.
 *
 * @return Array with valid items.
 * @throw string if one or more entry values did not validate.
 */
export declare function validateArray<T>(unsafeArray: PossibleArray<unknown>, validator: Validator<T>): ImmutableArray<T>;
/**
 * Validate the values of the entries in a dictionary object.
 *
 * @throw string if one or more entry values did not validate.
 */
export declare function validateDictionary<T>(unsafeDictionary: PossibleDictionary<unknown>, validator: Validator<T>): ImmutableDictionary<T>;
/**
 * Validate a data object with a set of validators.
 * - Defined props in the object will be validated against the corresponding validator.
 * - `undefined` props in the object will be set to the default value of that prop.
 * - `undefined` props after validation will not be set in the output object.
 *
 * @return Valid object.
 * @throw string if one or more props did not validate.
 */
export declare function validateData<T extends Data>(unsafeData: Data, validators: Validators<T>): T;
