export = SeamlessImmutable; declare namespace SeamlessImmutable { /** From type T, take all properties except those specified by K. */ type Omit = Pick>; type DeepPartial = { [P in keyof T]?: DeepPartial; }; interface MergeConfig { deep?: boolean | undefined; mode?: "replace" | "merge" | undefined; merger?(a: any, b: any, config: any): any; } interface ReplaceConfig { deep: boolean; } interface Options { prototype?: any; } interface AsMutableOptions { deep: TDeep; } interface ImmutableObjectMixin { set(property: K, value: T[K]): Immutable; set(property: string, value: TValue): Immutable; setIn(propertyPath: [K], value: T[K]): Immutable; setIn(propertyPath: [K, L], value: T[K][L]): Immutable; setIn( propertyPath: [K, L, M], value: T[K][L][M], ): Immutable; setIn( propertyPath: [K, L, M, N], value: T[K][L][M][N], ): Immutable; setIn< K extends keyof T, L extends keyof T[K], M extends keyof T[K][L], N extends keyof T[K][L][M], O extends keyof T[K][L][M][N], >( propertyPath: [K, L, M, N, O], value: T[K][L][M][N][O], ): Immutable; setIn(propertyPath: string[], value: TValue): Immutable; getIn(propertyPath: [K]): Immutable; getIn(propertyPath: [K], defaultValue: T[K]): Immutable; getIn(propertyPath: [K, L]): Immutable; getIn(propertyPath: [K, L], defaultValue: T[K][L]): Immutable; getIn( propertyPath: [K, L, M], ): Immutable; getIn( propertyPath: [K, L, M, N], ): Immutable; getIn( propertyPath: [K, L, M, N], defaultValue: T[K][L][M][N], ): Immutable; getIn< K extends keyof T, L extends keyof T[K], M extends keyof T[K][L], N extends keyof T[K][L][M], O extends keyof T[K][L][M][N], >( propertyPath: [K, L, M, N, O], ): Immutable; getIn< K extends keyof T, L extends keyof T[K], M extends keyof T[K][L], N extends keyof T[K][L][M], O extends keyof T[K][L][M][N], >( propertyPath: [K, L, M, N, O], defaultValue: T[K][L][M][N][O], ): Immutable; getIn(propertyPath: string[]): Immutable; getIn(propertyPath: string[], defaultValue: TValue): Immutable; asMutable(opts?: AsMutableOptions): { [K in keyof T]: Immutable }; asMutable(opts: AsMutableOptions): T; asMutable(opts: AsMutableOptions): T | { [K in keyof T]: Immutable }; merge(part: DeepPartial>, config?: MergeConfig): Immutable; update( property: K, updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; update( property: string, updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; updateIn( propertyPath: [K], updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; updateIn( propertyPath: [K, L], updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; updateIn( propertyPath: [K, L, M], updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; updateIn( propertyPath: [K, L, M, N], updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; updateIn< K extends keyof T, L extends keyof T[K], M extends keyof T[K][L], N extends keyof T[K][L][M], O extends keyof T[K][L][M][N], >( propertyPath: [K, L, M, N, O], updaterFunction: (value: Immutable, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; updateIn( propertyPath: string[], updaterFunction: (value: TValue, ...additionalParameters: any[]) => any, ...additionalArguments: any[] ): Immutable; without(property: K): Immutable; without(...properties: K[]): Immutable; without(filter: (value: T[K], key: K) => boolean): Immutable; replace(valueObj: S, options?: ReplaceConfig): Immutable; } type ImmutableObject = ImmutableObjectMixin & { readonly [P in keyof T]: Immutable }; /** An ImmutableArray provides read-only access to the array elements, and provides functions (such as `map()`) that return immutable data structures. */ type ImmutableArray = & Readonly> & ImmutableArray.Additions & ImmutableArray.Overrides & ImmutableArray.ReadOnlyIndexer; namespace ImmutableArray { /** New methods added by seamless-immutable. */ interface Additions { asMutable(opts?: AsMutableOptions): Array>; asMutable(opts: AsMutableOptions): T[]; asMutable(opts: AsMutableOptions): T[] | Array>; asObject( toKeyValue: (item: T) => [K, U[K]], ): Immutable; flatMap(mapFunction: (item: T) => TTarget): Immutable; } /** Custom implementation of the array functions, which return Immutable. */ interface Overrides { forEach( callbackfn: (value: Immutable, index: number, array: Immutable) => void, thisArg?: any, ): void; map( mapFuction: (item: Immutable, index: number, array: Immutable) => TTarget, ): Immutable; filter(filterFunction: (item: Immutable, index: number) => boolean): Immutable; slice(start?: number, end?: number): Immutable; concat(...arr: Array | Array> | Immutable>): Immutable; reduce( callbackfn: ( previousValue: Immutable, currentValue: Immutable, currentIndex: number, array: Immutable, ) => T, ): Immutable; reduce( callbackfn: ( previousValue: TTarget, currentValue: Immutable, currentIndex: number, array: Immutable, ) => TTarget, initialValue?: TTarget, ): Immutable; reduceRight( callbackfn: ( previousValue: Immutable, currentValue: Immutable, currentIndex: number, array: Immutable, ) => T, ): Immutable; reduceRight( callbackfn: ( previousValue: TTarget, currentValue: Immutable, currentIndex: number, array: Immutable, ) => TTarget, initialValue?: TTarget, ): Immutable; } /** Merging this into Overrides breaks stuff, so this is split out */ interface ReadOnlyIndexer { readonly [key: number]: Immutable; } /** These methods are banned by seamless-immutable. */ type MutatingArrayMethods = Extract< keyof any[], "push" | "pop" | "sort" | "splice" | "shift" | "unshift" | "reverse" | number >; /** NOTE: These methods mutate data, but seamless-immutable does not ban them. We will ban them in our type definitions. */ type AdditionalMutatingArrayMethods = Extract; /** The remaining properties on Array, after we remove the mutating functions and the wrapped non-mutating functions. */ type Remaining = Omit>; } /** An ImmutableDate disables the use of mutating functions like `setDate` and `setFullYear`. */ type ImmutableDate = ImmutableDate.Remaining & ImmutableDate.Additions; namespace ImmutableDate { /** New functions added by seamless-immutable. */ interface Additions { asMutable(): Date; } // These methods are banned by seamless-immutable type MutatingDateMethods = Extract< keyof Date, | "setDate" | "setFullYear" | "setHours" | "setMilliseconds" | "setMinutes" | "setMonth" | "setSeconds" | "setTime" | "setUTCDate" | "setUTCFullYear" | "setUTCHours" | "setUTCMilliseconds" | "setUTCMinutes" | "setUTCMonth" | "setUTCSeconds" | "setYear" >; /** Only allows Date methods, which are the getters. */ type Remaining = Omit; } type Immutable = T extends Promise ? Promise> : Immutable.MakeImmutable; namespace Immutable { type AnyFunction = (...args: any[]) => any; type AlreadyImmutable = ImmutableObject | ImmutableArray | ImmutableDate; type Primitive = boolean | number | string | symbol | AnyFunction | undefined | null; type CannotMakeImmutable = AlreadyImmutable | Primitive; type MakeImmutable = T extends CannotMakeImmutable ? T : T extends Array ? ImmutableArray : T extends Date ? ImmutableDate : ImmutableObject; } function from(obj: T, options?: Options): Immutable; function isImmutable(target: T | Immutable): target is Immutable; function ImmutableError(message: string): Error; function replace(obj: Immutable, valueObj: S, options?: ReplaceConfig): Immutable; function asMutable(obj: T[] | ImmutableArray, opts?: AsMutableOptions): T[]; function asMutable(obj: T[] | ImmutableArray, opts: AsMutableOptions): T[]; function asMutable(obj: T[] | ImmutableArray, opts: AsMutableOptions): T[] | Array>; function asMutable( obj: T | ImmutableObject, opts?: AsMutableOptions, ): { [K in keyof T]: Immutable }; function asMutable(obj: T | ImmutableObject, opts: AsMutableOptions): T; function asMutable(obj: T | ImmutableObject, opts: AsMutableOptions): T | { [K in keyof T]: Immutable }; } declare function SeamlessImmutable(obj: T, options?: SeamlessImmutable.Options): SeamlessImmutable.Immutable;