import type { MutableSymbolTable, RekeyableMap, SourceFile, SymbolTable, SystemHost } from "../core/types.js";
/**
 * Recursively calls Object.freeze such that all objects and arrays
 * referenced are frozen.
 *
 * Does not support cycles. Intended to be used only on plain data that can
 * be directly represented in JSON.
 */
export declare function deepFreeze<T>(value: T): T;
/**
 * Deeply clones an object.
 *
 * Does not support cycles. Intended to be used only on plain data that can
 * be directly represented in JSON.
 */
export declare function deepClone<T>(value: T): T;
/**
 * Checks if two objects are deeply equal.
 *
 * Does not support cycles. Intended to be used only on plain data that can
 * be directly represented in JSON.
 */
export declare function deepEquals(left: unknown, right: unknown): boolean;
export type EqualityComparer<T> = (x: T, y: T) => boolean;
/**
 * Check if two arrays have the same elements.
 *
 * @param equals Optional callback for element equality comparison.
 *               Default is to compare by identity using `===`.
 */
export declare function arrayEquals<T>(left: T[], right: T[], equals?: EqualityComparer<T>): boolean;
/**
 * Check if two maps have the same entries.
 *
 * @param equals Optional callback for value equality comparison.
 *               Default is to compare by identity using `===`.
 */
export declare function mapEquals<K, V>(left: Map<K, V>, right: Map<K, V>, equals?: EqualityComparer<V>): boolean;
export declare function getNormalizedRealPath(host: SystemHost, path: string): Promise<string>;
export declare function readUrlOrPath(host: SystemHost, pathOrUrl: string): Promise<SourceFile>;
export declare function resolveRelativeUrlOrPath(base: string, relativeOrAbsolute: string): string;
/**
 * A specially typed version of `Array.isArray` to work around [this issue](https://github.com/microsoft/TypeScript/issues/17002).
 */
export declare function isArray<T>(arg: T | {}): arg is T extends readonly any[] ? (unknown extends T ? never : readonly any[]) : any[];
/**
 * Check if argument is not undefined.
 */
export declare function isDefined<T>(arg: T | undefined): arg is T;
export declare function isWhitespaceStringOrUndefined(str: string | undefined): boolean;
export declare function firstNonWhitespaceCharacterIndex(line: string): number;
export declare function distinctArray<T, P>(arr: T[], keySelector: (item: T) => P): T[];
export declare function tryParseJson(content: string): any | undefined;
export declare function debounce<T extends (...args: any[]) => any>(fn: T, delayInMs: number): T;
/**
 * Remove undefined properties from object.
 */
export declare function omitUndefined<T extends Record<string, unknown>>(data: T): T;
/**
 * Extract package.json's tspMain entry point in a given path.
 * @param path Path that contains package.json
 * @param reportDiagnostic optional diagnostic handler.
 */
export declare function resolveTspMain(packageJson: any): string | undefined;
/**
 * A map keyed by a set of objects.
 *
 * This is likely non-optimal.
 */
export declare class MultiKeyMap<K extends readonly object[], V> {
    #private;
    get(items: K): V | undefined;
    set(items: K, value: V): void;
    private compositeKeyFor;
    private keyFor;
}
/**
 * A map with exactly two keys per value.
 *
 * Functionally the same as `MultiKeyMap<[K1, K2], V>`, but more efficient.
 * @hidden bug in typedoc
 */
export declare class TwoLevelMap<K1, K2, V> extends Map<K1, Map<K2, V>> {
    /**
     * Get an existing entry in the map or add a new one if not found.
     *
     * @param key1 The first key
     * @param key2 The second key
     * @param create A callback to create the new entry when not found.
     * @param sentinel An optional sentinel value to use to indicate that the
     *                 entry is being created.
     */
    getOrAdd(key1: K1, key2: K2, create: () => V, sentinel?: V): V;
}
export declare class Queue<T> {
    #private;
    constructor(elements?: T[]);
    isEmpty(): boolean;
    enqueue(...items: T[]): void;
    dequeue(): T;
}
/**
 * The mutable equivalent of a type.
 */
export type Mutable<T> = T extends SymbolTable ? T & MutableSymbolTable : T extends ReadonlyMap<infer K, infer V> ? Map<K, V> : T extends ReadonlySet<infer T> ? Set<T> : T extends readonly (infer V)[] ? V[] : {
    -readonly [P in keyof T]: T[P];
};
type MutableExt<T> = T extends SymbolTable ? T & MutableSymbolTable : T extends ReadonlyMap<infer K, infer V> ? Map<K, V> : T extends ReadonlySet<infer T> ? Set<T> : T extends readonly (infer V)[] ? V[] : {
    -readonly [P in keyof T]: T[P];
} & {
    __writableBrand: never;
};
/**
 * Casts away readonly typing.
 *
 * Use it like this when it is safe to override readonly typing:
 *   mutate(item).prop = value;
 */
export declare function mutate<T>(value: T): MutableExt<T>;
export declare function createStringMap<T>(caseInsensitive: boolean): Map<string, T>;
export declare function createRekeyableMap<K, V>(entries?: Iterable<[K, V]>): RekeyableMap<K, V>;
export {};
//# sourceMappingURL=misc.d.ts.map