declare type AliasConstr<AL extends string, AR extends string> = {
    <L, R>(data?: Map<L, R>): BiMap<L, R, AL, AR>;
    <T extends readonly (readonly [unknown, unknown])[]>(data: T): BiMap<T[number] extends [infer L, any] ? L : never, T[number] extends [any, infer R] ? R : never, AL, AR>;
    <L, R>(left: Set<L>, right: Set<R>): BiMap<L, R, AL, AR>;
    <T extends Record<L, R>, L extends string | symbol, R>(data: T): T extends Set<any> ? never : BiMap<L, R, AL, AR>;
};
declare class BiMapImpl<L, R, AL extends string = never, AR extends string = never> {
    private aliasLeft?;
    private aliasRight?;
    constructor(data?: Map<L, R> | readonly (readonly [L, R])[], aliasLeft?: AL, aliasRight?: AR);
    static from: AliasConstr<never, never>;
    private static fromSets;
    static alias: <LA extends string, RA extends string>(left: LA, right: RA) => AliasConstr<LA, RA>;
    private defineAlias;
    clone(): BiMapImpl<L, R, AL, AR>;
    reverse(): BiMapImpl<R, L, AR, AL>;
    clear(): this;
    get size(): number;
    [Symbol.iterator](): IterableIterator<[L, R]>;
    private proxy;
    private readonly data;
    readonly left: MapLike<L, R>;
    readonly right: MapLike<R, L>;
}
declare const _default: (new <L, R, AL extends string = never, AR extends string = never>(data?: Map<L, R> | readonly (readonly [L, R])[] | undefined, aliasLeft?: AL | undefined, aliasRight?: AR | undefined) => BiMap<L, R, AL, AR>) & typeof BiMapImpl;
export default _default;
/**
 * Bidirectional map. Maps two sets of keys in a one-to-one relation.
 *
 * Both sides are accessible (at .left & .right, or at their respective alias if
 * one was provided in the constructor) with an interface similar to that of the
 * built-in Map and the same iteration behavior.
 *
 * @example
 * ```
 * const nums = BiMap.from({ one: 1, two: 2 })
 *
 * // different ways of iterating over the entries
 * [...nums.left]                 // [['one',1], ['two',2]]
 * [...nums.right]                // [[1,'one'], [2,'two']]
 * [...nums.left.keys()]          // ['one', 'two']
 * [...nums.left.values()]        // [1, 2]
 * [...nums.right.keys()]         // [1, 2]
 * [...nums.right.values()]       // ['one', 'two']
 * [...nums]                      // [['one',1], ['two',2]]
 * [...nums.right.entries()]      // [[1,'one'], [2,'two']]
 * Object.fromEntries(nums.right) // { '1': 'one', '2': 'two' }
 *
 * // setting a value
 * nums.left.three = 3
 * // when accessing a property using bracket notation (i.e. nums.right[4]),
 * // JavaScript coerces the key to a string, so keys that aren't strings or
 * // symbols must be accessed using the same access methods known from Map.
 * nums.right.set(4, 'four')
 *
 * // remapping values
 * nums.left.tres = 3          // {one: 1, two: 2, tres: 3, four: 4}
 * nums.right.set(4, 'cuatro') // {one: 1, two: 2, tres: 3, cuatro: 4}
 *
 * // deleting
 * delete nums.left.tres    // {one: 1, two: 2, cuatro: 4}
 * nums.right.delete(4)     // {one: 1, two: 2}
 *
 * // reversing the map
 * const num2Name = nums.reverse()
 * console.log([...num2Name.left])                 // [[1,'one'], [2,'two']]
 * console.log(Object.fromEntries(num2Name.right)) // {one: 1, two: 2}
 *
 * // other methods known from built-in Map
 * nums.size               // 2
 * nums.[left|right].size  // 2
 * nums.clear() // equivalent to nums.[left|right].clear()
 * console.log(nums.size)  // 0
 * ```
 *
 * @example
 * ```
 * // giving aliases to both sides
 * const dictionary = new BiMap(
 *   [
 *     ['hello', 'hallo'],
 *     ['bye', 'tschüss'],
 *   ],
 *   'en',
 *   'de'
 * )
 *
 * dictionary.de.get('hallo') // 'hello'
 * dictionary.en.get('bye')   // 'tschüss'
 *
 * delete dictionary.de.hallo
 * console.log(Object.fromEntries(dictionary.en)) // { bye: 'tschüss' }
 *
 * // you can also use the BiMap.alias method:
 * BiMap.alias('en', 'de')<string, string>()
 * BiMap.alias('en', 'de')([['hello', 'hallo']])
 * BiMap.alias('en', 'de')(new Map<string, string>())
 * BiMap.alias('en', 'de')({ hello: 'hallo' })
 * BiMap.alias('en', 'de')(new Set(['hello']), new Set(['hallo']))
 *
 * // the same arguments can be used with BiMap.from, e.g.:
 * BiMap.from(new Set<number>(), new Set<number>())
 * ```
 */
export declare type BiMap<L, R, A extends string = never, B extends string = never> = Omit<BiMapImpl<L, R, A, B>, "clone" | "reverse"> & {
    clone(): BiMap<L, R, A, B>;
    reverse(): BiMap<R, L, B, A>;
} & {
    [K in A]: MapLike<L, R>;
} & {
    [K in B]: MapLike<R, L>;
};
declare type MapLike<K, V> = {
    keys(): IterableIterator<K>;
    values(): IterableIterator<V>;
    has(key: K): boolean;
    get(key: K): V | undefined;
    set<T extends V>(key: K, value: T): T;
    getOrSet(key: K, value: V): V;
    delete(key: K): boolean;
    clear(): MapLike<K, V>;
    size: number;
} & {
    [SK in Extract<K, string | symbol>]: V;
} & IterableIterator<[K, V]>;
