import * as e from "fp-ts/lib/Either";
import { EnforceNonEmptyRecord, SmartConstructor, SmartConstructorOptional } from "./utilTypes";
/**
 *
 * Given an object replaces all the values recursively with strings to describe an arbitrarily
 * nested object of validation errors
 *
 * @example
 * ```ts
 * type Person = {
 *   name: {
 *     display: StringOfLength<1, 30>
 *     full: StringOfLength<1, 100>
 *   },
 *   profilePicture: URL
 * }
 *
 * FieldError<Person> --> {
 *                          name?: {
 *                            display?: string;
 *                            full?: string;
 *                          };
 *                          profilePicture?: string;
 *                        }
 * ```
 */
declare type FieldError<T extends EnforceNonEmptyRecord<Record<PropertyKey, unknown>>> = Partial<{
    [key in keyof T]: T[key] extends Record<PropertyKey, unknown> ? FieldError<T[key]> : string;
}>;
/**
 * A ConstructorObj is the object passed to the mkSmartObject function. It should have
 * keys of the object to construct and values which are Smart Constructors. This types works
 * recursively to allow for nested Smart Objects.
 */
declare type ConstructorObj<T extends Record<PropertyKey, unknown>> = {
    [key in keyof T]: SmartConstructor<T[key]> | SmartConstructorOptional<T[key]> | (T[key] extends Record<PropertyKey, unknown> ? MkSmartObject<T[key]> : never);
};
declare type MkSmartObject<T extends Record<PropertyKey, unknown>> = (input: Record<PropertyKey, unknown>) => e.Either<FieldError<T>, T>;
export declare const mkSmartObject: <T extends Record<string | number | symbol, unknown>>(construct: ConstructorObj<T>) => MkSmartObject<T>;
export {};
