/**
 * Type predicate function that validates a value and narrows its type.
 *
 * Returns true if the value matches type T, allowing TypeScript to narrow
 * the type in the calling scope. This is the foundation for all type guard validators.
 *
 * @template T - The type to validate and narrow to
 * @param val - The value to validate
 * @returns Type predicate indicating whether val is of type T
 *
 * @example
 * const isString: ValidatorFn<string> = (val): val is string => typeof val === 'string';
 * if (isString(value)) {
 *   // value is narrowed to type: string
 * }
 */
export type ValidatorFn<T = unknown> = (val: unknown) => val is T;
/**
 * Metadata associated with a registered type guard validator.
 * Includes validator name, optional inner validators for composite types,
 * and optional constraint data for bounded types.
 *
 * @template Options - The constraint type (never if no constraints)
 */
export type GuardMeta<Options = never> = {
    /** Display name of the validator (without "is" prefix) */
    name: string;
    /** Optional inner validator for composite types (arrays, objects) */
    inner?: ValidatorFn<unknown>;
} & ([Options] extends [never] ? {
    constraint?: never;
    printConstraint?: never;
    printDiagnosis?: never;
} : {
    /** Constraint data (e.g., min/max bounds) */
    constraint: Options;
    /** Function to format constraint for display */
    printConstraint: (data: Options) => string;
    /** Function to generate diagnostic message for failed validation */
    printDiagnosis: (data: Options, val: unknown) => string;
});
/**
 * Retrieves metadata for a registered validator function.
 *
 * @template T - The validator's return type
 * @template O - The constraint type (defaults to never)
 * @param fn - The validator function to look up
 * @returns The validator's metadata, or undefined if not registered
 */
export declare const getMeta: <T, O = never>(fn: ValidatorFn<T>) => GuardMeta<O> | undefined;
/**
 * Registers a type guard validator function with metadata for diagnostic purposes.
 * This is the foundation for creating all type guard validators in the system.
 *
 * Two overloads:
 * 1. Simple guards (no constraints) - for primitives and simple structural types
 * 2. Constrained guards - for bounded types with validation constraints
 *
 * The function must be named (not anonymous) so the name can be extracted for diagnostics.
 *
 * @template T - The type the guard validates
 * @param fn - The validator function with type predicate
 * @param meta - Optional metadata (name, inner validators)
 * @returns The same validator function, now registered in the guard registry
 *
 * @example
 * // Simple guard
 * const isString = guard(function isString(val: unknown): val is string {
 *   return typeof val === 'string';
 * });
 */
export declare function guard<T>(fn: ValidatorFn<T>, meta?: {
    name?: string;
    inner?: ValidatorFn<unknown>;
}): ValidatorFn<T>;
/**
 * Registers a constrained type guard validator with diagnostic metadata.
 *
 * @template T - The type the guard validates
 * @template Options - The constraint type
 * @param fn - The validator function with type predicate
 * @param meta - Metadata including constraint, display, and diagnostic functions
 * @returns The same validator function, now registered in the guard registry
 *
 * @example
 * // Constrained guard
 * const isBounded = guard<number, { min: number }>(
 *   function isBounded(val: unknown): val is number {
 *     return typeof val === 'number' && val >= 0;
 *   },
 *   {
 *     constraint: { min: 0 },
 *     printConstraint: (c) => `(>=${c.min})`,
 *     printDiagnosis: (c, val) => `got ${val}, expected >= ${c.min}`
 *   }
 * );
 */
export declare function guard<T, Options>(fn: ValidatorFn<T>, meta: {
    name?: string;
    inner?: ValidatorFn<unknown>;
    constraint: Options;
    printConstraint: (data: Options) => string;
    printDiagnosis: (data: Options, val: unknown) => string;
}): ValidatorFn<T>;
/**
 * Generates a human-readable type name for a validator function.
 * Includes constraints and nested types in the output.
 *
 * @template T - The validator's return type
 * @param fn - The validator function
 * @returns A formatted string representing the full type (e.g., "Array<String>", "Number(0..255)")
 *
 * @example
 * getFullTypeName(isString) // "String"
 * getFullTypeName(isUint8) // "Number(0..255)"
 * getFullTypeName(isStringArray) // "Array<String>"
 */
export declare const getFullTypeName: <T>(fn: ValidatorFn<T>) => string;
/**
 * Identifies the runtime type of a value using registered validators.
 * Returns a human-readable string describing the value's type structure.
 *
 * For primitives, tries to match against registered validators.
 * For arrays and objects, recursively identifies nested structure.
 *
 * @param val - The value to identify
 * @returns A string describing the value's type (e.g., "string", "[number, string]", "{x: string, y: number}")
 *
 * @example
 * identify("hello") // "string"
 * identify([1, 2, 3]) // "[number, number, number]"
 * identify({ x: "a", y: 5 }) // "{x: string, y: number}"
 */
export declare const identify: (val: unknown) => string;
/**
 * Schema definition node - can be a literal, validator, or nested object.
 * Used to define expected structure for validation.
 */
export type SchemaNode = string | number | boolean | null | ValidatorFn | {
    [key: string]: SchemaNode;
};
/**
 * Schema definition for object validation.
 * Maps property names to their expected types (validators, literals, or nested objects).
 * This is the object-specific variant of SchemaNode.
 */
export interface SchemaObject {
    [key: string]: SchemaNode;
}
/**
 * Infers the TypeScript type from a schema definition.
 * Recursively extracts types from validators and nested objects.
 *
 * @template S - The schema to infer from
 * @returns The inferred TypeScript type
 *
 * @example
 * const schema = { name: isString, age: isNumber };
 * type Person = InferSchemaType<typeof schema>; // { name: string; age: number }
 */
export type InferSchemaType<S> = S extends (val: unknown) => val is infer T ? T : S extends object ? {
    [K in keyof S]: InferSchemaType<S[K]>;
} : S;
/**
 * Human-readable schema description - the output of describeSchema.
 * Mirrors SchemaNode structure but with validators converted to type names.
 */
export type SchemaDescription = string | number | boolean | null | {
    [key: string]: SchemaDescription;
};
/**
 * Recursively converts a schema definition into a human-readable description.
 * Replaces validator functions with their type names while preserving structure.
 *
 * @param schema - The schema definition to describe
 * @returns A human-readable description of the schema structure
 *
 * @example
 * describeSchema({ x: isString, y: isNumber })
 * // Returns: { x: "String", y: "Number" }
 *
 * describeSchema({ items: isStringArray })
 * // Returns: { items: "Array<String>" }
 */
export declare const describeSchema: (schema: SchemaNode) => SchemaDescription;
/**
 * Recursively validates a value and collects detailed error messages.
 * Provides path-aware diagnostics showing exactly where and why validation failed.
 *
 * The function:
 * 1. Validates the value using the provided validator
 * 2. If validation fails, adds a detailed error message with path
 * 3. If validation passes but the type has inner validators (array/object elements),
 *    recursively validates nested values
 * 4. Returns all collected errors with proper indentation and context
 *
 * @template T - The expected type
 * @param fn - The validator function to use
 * @param val - The value to validate
 * @param path - The current path for error reporting (default: "value")
 * @param errors - Accumulated error messages (internal use)
 * @returns Array of error messages (empty if validation succeeds)
 *
 * @example
 * const validator = isArrayOfLength(isUint8, 3);
 * const errors = diagnose(validator, [1, 2, 300]);
 * // Returns: [
 * //   "value should have type Array[3]<Number(0..255)>",
 * //   "  value[2]: expected Number(0..255), got 300 which exceeds maximum 255"
 * // ]
 */
export declare const diagnose: <T>(fn: ValidatorFn<T>, val: unknown, path?: string, errors?: string[]) => string[];
