import { Type, TypeCategory } from "../internal.mjs";
type ElementOf<T> = T extends readonly (infer E)[] ? E : (T extends Set<infer E> ? E : never);
type MapKey<T> = T extends Map<infer K, any> ? K : never;
type MapValue<T> = T extends Map<any, infer V> ? V : never;
type ClassConstructor<T> = abstract new (...args: any[]) => NonNullable<T>;
type Comparable = number | string | boolean;
type NonUndefinable<T> = Exclude<T, undefined>;
/**
 * Indicates if an object is an instance of a type. To convert a type to an object, use
 * `prototype` such as `Error.prototype`. To convert an object to a type, use
 * `constructor` such as `instance.constructor`.
 *
 * @param child - the child class
 * @param parent - the parent class
 * @returns `true` if `child` extends `parent`; false if
 *   `parent` or `child` are `undefined` or `null`; false if `child` does not extend `parent`
 */
declare function classExtends(child: ClassConstructor<unknown>, parent: ClassConstructor<unknown>): boolean;
/**
 * Throws an `Error` if `condition` is false.
 *
 * @param condition - a condition
 * @param error - the type of error to throw (Default: `Error`)
 * @param message - the error message to use on failure
 * @throws AssertionError if `condition` is false
 */
declare function assert(condition: boolean, error?: (message?: string) => Error, message?: string): asserts condition;
/**
 * Ensures that an object is defined.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @returns `true`
 * @throws TypeError if:
 * <ul>
 *   <li>`name` is not a string</li>
 *   <li>if `value` is `undefined`</li>
 * </ul>
 */
declare function requireThatValueIsDefined(value: unknown, name: string): boolean;
/**
 * Ensures that an object is defined and not null.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @returns `true`
 * @throws TypeError if:
 * <ul>
 *   <li>`name` is not a string</li>
 *   <li>if `value` is `undefined` or `null`</li>
 * </ul>
 */
declare function requireThatValueIsNotNull(value: unknown, name: string): boolean;
/**
 * Ensures that an object is defined and not null.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @returns `true`
 * @throws AssertionError if:
 * <ul>
 *   <li>`name` is not a string</li>
 *   <li>if `value` is `undefined` or `null`</li>
 * </ul>
 */
declare function assertThatValueIsNotNull(value: unknown, name: string): void;
/**
 * Requires that an object has the expected type.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @param type - `value`'s expected type
 * @returns `true`
 * @throws TypeError if `value` does not have the expected `type`. If `name` is not a string.
 */
declare function requireThatType(value: unknown, name: string, type: Type): boolean;
/**
 * Requires that a value has the expected type if assertions are enabled. We assume that
 * `assert()` will be stripped out at build-time if assertions are disabled.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @param type - `value`'s expected type
 * @returns `true`
 * @throws TypeError if `value` does not have the expected `type`. If `name` is not a string.
 */
declare function assertThatType(value: unknown, name: string, type: Type): void;
/**
 * Requires that an object has the expected type category.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @param typeCategory - `value`'s expected type category
 * @param typeGuard - (optional) for certain types, such as Typescript interfaces, runtime validation is not
 * possible. In such a case, use a type guard to check if the value satisfies the type condition.
 * @returns `true`
 * @throws TypeError if `value` does not have the expected `typeCategory`. If `name` is not a string.
 */
declare function requireThatTypeCategory(value: unknown, name: string, typeCategory: TypeCategory, typeGuard?: (value: unknown) => boolean): boolean;
/**
 * Requires that a value has the expected type category if assertions are enabled. We assume that
 * `assert()` will be stripped out at build-time if assertions are disabled.
 *
 * @param value - the value of a parameter
 * @param name  - the name of the parameter
 * @param category - `value`'s expected type category
 * @param typeGuard - (optional) for certain types, such as Typescript interfaces, runtime validation is not
 * possible. In such a case, use a type guard to check if the value satisfies the type condition.
 * @returns `true`
 * @throws TypeError if `value` does not have the expected `typeCategory` category. If `name` is not a string.
 */
declare function assertThatTypeCategory(value: unknown, name: string, category: TypeCategory, typeGuard?: (value: unknown) => boolean): void;
/**
 * Requires that an object is an instance of `type`.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @param type - the class that `value` is expected to be an instance of. This may not reference
 * an interface or abstract class because
 * <a href="https://stackoverflow.com/a/47082428/14731">Typescript does not expose them at runtime</a>.
 * @returns `true`
 * @throws TypeError if `value` is not an instance of `type`.
 * If `name` is not a string.
 */
declare function requireThatInstanceOf(value: unknown, name: string, type: ClassConstructor<unknown> | Record<string | number, string | number>): boolean;
/**
 * Requires that an object is an instance of the expected type.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @param type - the class the value is expected to be an instance of
 * @throws TypeError if `value` is not an instance of `type`.
 * If `name` is not a string.
 */
declare function assertThatInstanceOf<T>(value: T, name: string, type: ClassConstructor<T>): void;
/**
 * Requires that a string is not empty.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @returns `true`
 * @throws TypeError if `name` or `value` are empty.
 * If `name` is not a string.
 */
declare function requireThatStringIsNotEmpty(value: string, name: string): boolean;
/**
 * Requires that a string is not empty.
 *
 * @param value - the value of a parameter
 * @param name - the name of the parameter
 * @returns `true`
 * @throws TypeError if `name` or `value` are empty.
 * If `name` is not a string.
 */
declare function assertThatStringIsNotEmpty(value: string, name: string): void;
/**
 * Converts an internal value to a string.
 *
 * @param value - a value
 * @returns the string representation of the value
 */
declare function internalValueToString(value: unknown): string;
/**
 * Quotes a String, escaping any nested quotes.
 *
 * @param value - a `String`
 * @returns the quoted string
 */
declare function quoteString(value: string): string;
/**
 * Returns the superclass of a value's type.
 *
 * @param value - a value
 * @returns `null` if the type does not have a superclass
 */
declare function getSuperclass(value: ClassConstructor<unknown>): ClassConstructor<unknown> | null;
/**
 * @param value - a name
 * @param name - the name of the name variable
 * @throws TypeError if `name` or `value` are not a string
 * @throws RangeError if `value` is empty
 */
declare function verifyName(value: string, name: string): void;
export type { ElementOf, MapKey, MapValue, ClassConstructor, Comparable, NonUndefinable };
export { classExtends, assert, requireThatValueIsDefined, requireThatValueIsNotNull, assertThatValueIsNotNull, requireThatType, assertThatType, requireThatTypeCategory, assertThatTypeCategory, requireThatInstanceOf, assertThatInstanceOf, requireThatStringIsNotEmpty, assertThatStringIsNotEmpty, internalValueToString, getSuperclass, verifyName, quoteString };
