import type { DeepPartial, DeepReadonly, DeepRequired } from 'ts-essentials';
/**
 * checks if `item` is an object (it may be an array, ...)
 */
export declare function isObjectOrArray(item: unknown): boolean;
export type MergeableRecord = Record<string, unknown>;
export type MergeableArray = unknown[];
export type Mergeable = MergeableRecord | MergeableArray;
type OrReadonly<T> = T | Readonly<T> | DeepReadonly<T>;
/**
 * Given two objects deeply merges them, if an object is an array it will merge the array values!
 * Guarantees some type safety by requiring objects to merge to be from the same type (allows undefined)
 * @see {@link deepMergeObjectInPlace} to merge into an existing object
 */
export declare function deepMergeObject<T extends Mergeable>(base: Required<OrReadonly<T>>, addon?: T | DeepPartial<T> | Partial<T>): Required<T>;
export declare function deepMergeObject<T extends Mergeable>(base: DeepRequired<OrReadonly<T>>, addon?: T | DeepPartial<T> | Partial<T>): DeepRequired<T>;
export declare function deepMergeObject<T extends Mergeable>(base: OrReadonly<T>, addon?: DeepPartial<T> | Partial<T>): T;
export declare function deepMergeObject(base: Mergeable, addon: Mergeable): Mergeable;
export declare function deepMergeObject(base?: Mergeable, addon?: Mergeable): Mergeable | undefined;
/**
 * Given two objects deeply merges them, if an object is an array it will merge the array values!
 * Modifies the `base` object in place and also returns it.
 * Guarantees some type safety by requiring objects to merge to be from the same type (allows undefined)
 * @see {@link deepMergeObject} to create a new merged object
 */
export declare function deepMergeObjectInPlace<T extends Mergeable>(base: T, addon?: DeepPartial<T> | Partial<T>): T;
export declare function deepMergeObjectInPlace<T extends Mergeable>(base: T | undefined, addon?: DeepPartial<T> | Partial<T>): T | undefined;
type Defined<T> = Exclude<T, undefined>;
type DefinedRecord<T> = {
    [K in keyof T as T[K] extends undefined ? never : K]: Defined<T[K]>;
};
export declare function compactRecord<T extends Record<string, unknown>>(record: T): DefinedRecord<T>;
export declare function compactRecord(record: undefined): undefined;
export declare function compactRecord<T extends Record<string, unknown>>(record: T | undefined): DefinedRecord<T> | undefined;
type Primitive = string | number | boolean | bigint | symbol | null | undefined | Date | Function;
/**
 * Given an object type `T`, produces a union of string literal types representing all possible paths to primitive values within that object.
 * Sadly, right now, the ts-essential paths property breaks when it comes to deeper nested objects
 */
export type AutocompletablePaths<T, Prefix extends string = ''> = T extends Primitive | readonly unknown[] ? never : {
    [K in keyof T & string]: `${Prefix}${K}` | (T[K] extends Primitive | readonly unknown[] ? never : AutocompletablePaths<T[K], `${Prefix}${K}.`>);
}[keyof T & string];
/**
 * This is a version of a deep clone that preserves unclonable values (like functions, symbols, ...) by keeping the same reference to them.
 */
export declare function deepClonePreserveUnclonable<T>(obj: T): T;
export {};
