import { IInterceptor, IKeyValueMap, IMapDidChange, IMapWillChange, Lambda } from "mobx";
import { IAnyType, IType, ExtractCSTWithSTN, IHooksGetter } from "../../internal";
/** @hidden */
export interface IMapType<IT extends IAnyType> extends IType<IKeyValueMap<IT["CreationType"]> | undefined, IKeyValueMap<IT["SnapshotType"]>, IMSTMap<IT>> {
    hooks(hooks: IHooksGetter<IMSTMap<IT>>): IMapType<IT>;
}
/** @hidden */
export interface IMSTMap<IT extends IAnyType> {
    clear(): void;
    delete(key: string): boolean;
    forEach(callbackfn: (value: IT["Type"], key: string | number, map: this) => void, thisArg?: any): void;
    get(key: string | number): IT["Type"] | undefined;
    has(key: string | number): boolean;
    set(key: string | number, value: ExtractCSTWithSTN<IT>): this;
    readonly size: number;
    put(value: ExtractCSTWithSTN<IT>): IT["Type"];
    keys(): IterableIterator<string>;
    values(): IterableIterator<IT["Type"]>;
    entries(): IterableIterator<[string, IT["Type"]]>;
    [Symbol.iterator](): IterableIterator<[string, IT["Type"]]>;
    /** Merge another object into this map, returns self. */
    merge(other: IMSTMap<IType<any, any, IT["TypeWithoutSTN"]>> | IKeyValueMap<ExtractCSTWithSTN<IT>> | any): this;
    replace(values: IMSTMap<IType<any, any, IT["TypeWithoutSTN"]>> | IKeyValueMap<ExtractCSTWithSTN<IT>> | any): this;
    toJSON(): IKeyValueMap<IT["SnapshotType"]>;
    toString(): string;
    [Symbol.toStringTag]: "Map";
    /**
     * Observes this object. Triggers for the events 'add', 'update' and 'delete'.
     * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
     * for callback details
     */
    observe(listener: (changes: IMapDidChange<string, IT["Type"]>) => void, fireImmediately?: boolean): Lambda;
    intercept(handler: IInterceptor<IMapWillChange<string, IT["Type"]>>): Lambda;
}
/**
 * `types.map` - Creates a key based collection type who's children are all of a uniform declared type.
 * If the type stored in a map has an identifier, it is mandatory to store the child under that identifier in the map.
 *
 * This type will always produce [observable maps](https://mobx.js.org/api.html#observablemap)
 *
 * Example:
 * ```ts
 * const Todo = types.model({
 *   id: types.identifier,
 *   task: types.string
 * })
 *
 * const TodoStore = types.model({
 *   todos: types.map(Todo)
 * })
 *
 * const s = TodoStore.create({ todos: {} })
 * unprotect(s)
 * s.todos.set(17, { task: "Grab coffee", id: 17 })
 * s.todos.put({ task: "Grab cookie", id: 18 }) // put will infer key from the identifier
 * console.log(s.todos.get(17).task) // prints: "Grab coffee"
 * ```
 *
 * @param subtype
 * @returns
 */
export declare function map<IT extends IAnyType>(subtype: IT): IMapType<IT>;
/**
 * Returns if a given value represents a map type.
 *
 * @param type
 * @returns `true` if it is a map type.
 */
export declare function isMapType(type: unknown): type is IMapType<IAnyType>;
