// Type definitions for Seamless-immutable 7.1 // Project: https://github.com/rtfeldman/seamless-immutable // Definitions by: alex3165 // Stepan Burguchev // Geir Sagberg // Richard Honor // Paul Huynh // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 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; mode?: 'replace' | 'merge'; 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( 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( propertyPath: [ K, L, M, N, O ]): Immutable; getIn( 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: T[K], ...additionalParameters: any[]) => any, ...additionalArguments: any[]): Immutable; update(property: string, updaterFunction: (value: TValue, ...additionalParameters: any[]) => any, ...additionalArguments: any[]): Immutable; updateIn( propertyPath: [ K ], updaterFunction: (value: T[K], ...additionalParameters: any[]) => any, ...additionalArguments: any[]): Immutable; updateIn( propertyPath: [ K, L ], updaterFunction: (value: T[K][L], ...additionalParameters: any[]) => any, ...additionalArguments: any[]): Immutable; updateIn( propertyPath: [ K, L, M ], updaterFunction: (value: T[K][L][M], ...additionalParameters: any[]) => any, ...additionalArguments: any[]): Immutable; updateIn( propertyPath: [ K, L, M, N ], updaterFunction: (value: T[K][L][M][N], ...additionalParameters: any[]) => any, ...additionalArguments: any[]): Immutable; updateIn( propertyPath: [ K, L, M, N, O ], updaterFunction: (value: T[K][L][M][N][O], ...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) => 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; /** 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; /** 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; } declare function SeamlessImmutable(obj: T, options?: SeamlessImmutable.Options): SeamlessImmutable.Immutable;