import { Mutable as Mutable_, OptionalKeys, Primitive, RequiredKeys } from "./types";
/**
* Recursively merges `A` and `B`. If a property in `A` and `B` is of a
* different type (i.e. it's not an array, Set, Map, or plain object in both,
* the value from `B` will be used in the result).
*
* If there are self-references in the cloned values, array / Set items, or Map
* keys or values, they will also be self-referencing in the result.
*/
declare const merge: (a: A, b: B) => Merge;
export default merge;
export declare type Merge = A extends Primitive ? Mutable : Merge_, Mutable>;
declare type Merge_ = Extract | MergeList | MergeSet | MergeMap | MergeObject;
declare type MergeSet = B extends Set ? (A extends Set ? Set : B) : never;
declare type MergeMap = B extends Map ? (A extends Map ? Map : B) : never;
declare type MergeObject = B extends Record ? (A extends Record ? MergeObject_ : never) : never;
declare type MergeObject_ = MakeOptional<{
[K in keyof A | keyof B]: K extends keyof B ? (K extends keyof A ? (Merge | (K extends OptionalKeys ? A[K] : never)) : B[K]) : K extends keyof A ? A[K] : never;
}, Exclude, RequiredKeys> | Exclude, RequiredKeys>>;
declare type MergeList = A extends unknown[] ? (B extends unknown[] ? (B[number][] extends Required ? MergeArray : A[number][] extends Required ? MergeArray : MergeTuple) : never) : never;
declare type MergeTuple = B extends [
infer H,
...infer T
] ? MergeTuple<[...A, H], T> : A;
declare type MergeArray = (A[number] | B[number])[];
declare type MakeOptional = FlattenIntersection> & {
[K in O]?: T[K];
}>;
declare type FlattenIntersection = {
[K in keyof T]: T[K];
};
declare type Mutable = T extends Set | Map ? T : Mutable_;