import { TypePredicate } from "../type/type.js";
import { Pair } from "../array/array.js";
/**
 * A type for representing a class
 */
export type Constructor<T extends object = any> = Function & {
    prototype: T;
};
/**
 * A type for representing a pair of object's keys-values
 */
export type KeyValues<T extends any = any> = Pair<KeyArray, T[]>;
/**
 * Type for representing a converted object key
 */
export type ObjectKey = string | symbol;
export type FinalKeys = ObjectKey[];
/**
 * Type for representing an object key
 */
export type KeyArray = PropertyKey[];
/**
 * Type for representing a shape of an object
 */
export type ShapeArg = KeyArray | {
    [x: PropertyKey]: ((x?: any) => boolean) | null | undefined;
};
/**
 * Returns the pair of keys and values of the given object
 */
export declare const kv: (obj: object) => [(string | symbol)[], any[]];
/**
 * Creates a new object using the pair of keys and values
 */
export declare const dekv: <T extends unknown = any>([keys, values]: KeyValues<T>) => Record<ObjectKey, T>;
/**
 * Creates a predicate for type-checking object-shapes.
 *
 * For `true`, mandates that argument be of `typeof x === "object"`. For `null`, returns `false`
 *
 * @param properties The basic object shape. If an array - items from the array are treated as keys to be checked for presence on the passed `x`. Otherwise - an object, keys of which correspond to property names to be proven to be present, and to be passing of the predicates assigned to the respective keys. Defaults to `[]`
 * @param lacks The array of keys to be shown to definitively not be present on the object. Checked before `optional`. Defaults to `[]`
 * @param optional The array of properties to be allowed on the object in the event that `isStrict` is set to `true`. Defaults to `[]`
 * @param isStrict The flag for indicating whether the shape to be checked for is "strict", meaning - whether any properties other than `properties` and `optional` are allowed. Defaults to `false`
 *
 * @example
 *
 * interface IThing {
 * 	eatable: any
 * 	fruit: bool
 * }
 *
 * interface Fruit extends IThing {
 * 	eatable: true
 * 	fruit: true
 * }
 *
 * interface Shelf extends IThing {
 * 	fruit: false
 * 	eatable: "maybe???"
 * 	robust: true
 * }
 *
 * const makeThing = (eatable: any, fruit: bool): IThing => ({ eatable, fruit })
 * const makeFruit = (): Fruit => makeThing(true, true)
 * const makeShelf = (): Shelf => { ...makeThing("maybe???", false), robust: true }
 *
 * const isThing = structCheck<IThing>({
 * 	eatable: T,
 * 	fruit: isBoolean,
 * })
 *
 * const isThingExact = structCheck<IThing>({
 * 	eatable: T,
 * 	fruit: isBoolean,
 * }, [], [], true)
 *
 * const isFruit = structCheck<Fruit>({
 * 	eatable: eqcurry(true),
 * 	fruit: eqcurry(true),
 * })
 *
 * const isShelf = structCheck<Shelf>({
 * 	eatable: eqcurry("maybe???"),
 * 	fruit: eqcurry(false)
 * })
 *
 * const apple = makeFruit()
 * const shelf = makeShelf()
 *
 * isThing(shelf) // true
 * isFruit(shelf) // false
 * isShelf(shelf) // true
 *
 * isThing(fruit) // true
 * isFruit(fruit) // true
 * isShelf(fruit) // false
 */
export declare function structCheck<Type extends object = object>(properties: ShapeArg, lacks?: KeyArray, optional?: KeyArray, isStrict?: boolean): TypePredicate<Type>;
/**
 * Returns the list of keys of a given object [includes the prototypes]
 */
export declare function keys(object: object): FinalKeys;
/**
 * Returns the array of object values [includes the prototypes]
 */
export declare function values(object: object): any[];
/**
 * Returns the array of string keys of a given object [includes the prototypes]
 */
export declare function recursiveStringKeys(object: object): string[];
/**
 * Returns the array of values of a given object at string keys [includes the prototypes]
 */
export declare function recursiveStringValues(object: object): any[];
/**
 * Returns the array of symbol keys of a given object [includes the prototypes]
 */
export declare function recursiveSymbolKeys(object: object): symbol[];
/**
 * Returns the array of values of a given object at symbol keys [includes the prototypes]
 */
export declare const recursiveSymbolValues: (object: object) => any[];
/**
 * Returns the pair of own keys and own properties of a given object
 */
export declare const ownProperties: (object: object) => [FinalKeys, any[]];
/**
 * Returns the own keys of a given object
 */
export declare function ownKeys(object: object): (string | symbol)[];
/**
 * Returns the own values of a given object
 */
export declare function ownValues(object: object): any[];
/**
 * Alias of 'Object.getPrototypeOf'
 */
export declare const prototype: (o: any) => any;
/**
 * Makes a shallow copy of a given object
 */
export declare const copy: <T extends object = object>(x: T) => T;
/**
 * Returns the object containing all the property descriptors on a given object `object` [includes the prototypes, respects inheritance],
 * up to the point of meeting the object of `commonPrototype` in the prototype chain (defaults to `Object.prototype`).
 */
export declare function propertyDescriptors(object: object, commonPrototype?: object): object & {
    [x: string]: PropertyDescriptor;
};
/**
 * Returns a new object containing all the own properties of `atobj` not present in `inobj`
 */
export declare function findOwnMissing(inobj: object, atobj: object): object;
/**
 * Allocates a new empty array
 */
export declare const empty: () => {};
/**
 * Creates a function that returns the shallow copy of `object` [useful for preserving the object's]
 */
export declare const allocator: <T extends object = object>(object: T) => () => T;
/**
 * Returns whether the two given objects are the same up to direct equivalence of keys' names,
 * and equivalence of values' arrays via 'array.same' with `pred` predicate
 */
export declare const same: (x: object, y: object, pred?: (x?: any, y?: any, i?: number) => boolean) => boolean;
/**
 * Recursively compares the two objects `x` and `y`, applying
 * `pred(x[i], y[i], i)` on all the values of `x` and `y` that aren't objects themselves.
 *
 * `pred` defaults to `equals`
 */
export declare function recursiveSame(x: object, y: object, pred?: (x?: any, y?: any, i?: number) => boolean): boolean;
/**
 * Returns a copy of a given object without the provided properties `props`
 */
export declare function withoutProperties(...props: ObjectKey[]): (object: object) => object;
/**
 * Returns a function for obtaining `x[name]`
 */
export declare const prop: (name: string) => (x: object) => any;
/**
 * Alias of 'Object.defineProperty'
 */
export declare const propDefine: <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T;
/**
 * Alias of 'Object.defineProperties'
 */
export declare const propsDefine: <T>(o: T, properties: PropertyDescriptorMap & ThisType<any>) => T;
/**
 * Defines a property with a name `name` and value described by the property-descriptor `value`
 * on the `Extended.prototype`
 */
export declare const protoProp: (Extended: Constructor, name: PropertyKey, value: PropertyDescriptor) => any;
/**
 * Defines the properties described by the given property-descriptor-map `properties` on `Extended.prototype`
 */
export declare const extendPrototype: (Extended: Constructor, properties: PropertyDescriptorMap) => any;
export * as classes from "./classes.js";
export * as descriptor from "./descriptor.js";
