/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { Brand } from "./brand.js";
import type { Opaque } from "./opaque.js";
import type { Invariant } from "./typeCheck.js";
/**
 * Key in a {@link BrandedMapSubset}.
 * @remarks
 * Due to the `TContent` type parameter being invariant (which it has to be since keys are used to both read and write data),
 * generic collections end up needing to constrain their key's `TContent` to `any`.
 */
export type BrandedKey<TKey, TContent> = TKey & Invariant<TContent>;
export type BrandedKeyContent<TKey extends BrandedKey<unknown, any>> = TKey extends BrandedKey<unknown, infer TContent> ? TContent : never;
/**
 * A Map where the keys carry the types of values which they correspond to.
 *
 * Example usage:
 * ```typescript
 * type FooSlot<TContent> = BrandedKey<Opaque<Brand<number, "FooSlot">>, TContent>;
 * const counterSlot = brandedSlot<FooSlot<number>>();
 * const slots: BrandedMapSubset<FooSlot<any>> = new Map();
 * slots.set(counterSlot, slots.get(counterSlot) ?? 0 + 1);
 * ```
 *
 * @remarks
 * These APIs are designed so that a Map can be used to implement this type.
 */
export interface BrandedMapSubset<K extends BrandedKey<unknown, any>> {
    get<K2 extends K>(key: K2): BrandedKeyContent<K2> | undefined;
    has(key: K): boolean;
    set<K2 extends K>(key: K2, value: BrandedKeyContent<K2>): this;
    delete(key: K): boolean;
}
/**
 * Version of {@link getOrCreate} with better typing for {@link BrandedMapSubset}.
 * @privateRemarks
 * Only infers type from key to avoid inferring `any` from map's key.
 */
export declare function getOrCreateSlotContent<K, V>(map: NoInfer<BrandedMapSubset<BrandedKey<K, V>>>, key: BrandedKey<K, V>, defaultValue: NoInfer<(key: BrandedKey<K, V>) => V>): V;
/**
 * Define a strongly typed slot in which data can be stored in a {@link BrandedMapSubset}.
 */
export declare function brandedSlot<TSlot extends BrandedKey<number | Opaque<Brand<number, string>>, any>>(): TSlot;
//# sourceMappingURL=brandedMap.d.ts.map