diff --git a/types/seamless-immutable/index.d.ts b/types/seamless-immutable/index.d.ts index b781523ef2..21474f3a6d 100644 --- a/types/seamless-immutable/index.d.ts +++ b/types/seamless-immutable/index.d.ts @@ -3,8 +3,9 @@ // Definitions by: alex3165 // Stepan Burguchev // Geir Sagberg +// Richard Honor // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.4 +// TypeScript Version: 2.8 export = SeamlessImmutable; @@ -31,17 +32,17 @@ declare namespace SeamlessImmutable { } interface ImmutableObjectMixin { - set(property: K, value: T[K]): ImmutableObject; - set(property: string, value: TValue): ImmutableObject; + set(property: K, value: T[K]): Immutable; + set(property: string, value: TValue): Immutable; - setIn(propertyPath: [ K ], value: T[K]): ImmutableObject; - setIn(propertyPath: [ K, L ], value: T[K][L]): ImmutableObject; - setIn(propertyPath: [ K, L, M ], value: T[K][L][M]): ImmutableObject; + 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]): ImmutableObject; + 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]): ImmutableObject; - setIn(propertyPath: string[], value: TValue): ImmutableObject; + 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; @@ -59,48 +60,48 @@ declare namespace SeamlessImmutable { asMutable(opts?: AsMutableOptions): T; - merge(part: DeepPartial, config?: MergeConfig): ImmutableObject; + merge(part: DeepPartial, config?: MergeConfig): Immutable; - update(property: K, updaterFunction: (value: T[K], ...additionalParameters: any[]) => any, ...additionalArguments: any[]): ImmutableObject; - update(property: string, updaterFunction: (value: TValue, ...additionalParameters: any[]) => any, ...additionalArguments: any[]): ImmutableObject; + 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[]): ImmutableObject; + 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[]): ImmutableObject; + 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[]): ImmutableObject; + 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[]): ImmutableObject; + 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[]): ImmutableObject; - updateIn(propertyPath: string[], updaterFunction: (value: TValue, ...additionalParameters: any[]) => any, ...additionalArguments: any[]): ImmutableObject; + 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): ImmutableObject; - without(...properties: K[]): ImmutableObject; - without(filter: (value: T[K], key: K) => boolean): ImmutableObject; + without(property: K): Immutable; + without(...properties: K[]): Immutable; + without(filter: (value: T[K], key: K) => boolean): Immutable; - replace(valueObj: S, options?: ReplaceConfig): ImmutableObject; + replace(valueObj: S, options?: ReplaceConfig): Immutable; } - interface ImmutableArrayMixin { - asMutable(opts?: AsMutableOptions): T[]; - asObject(toKeyValue: (item: T) => [string, any]): ImmutableObject; - flatMap(mapFunction: (item: T) => TTarget[]): ImmutableArray; + interface ImmutableArrayMixin> { + asMutable(opts?: AsMutableOptions): T; + asObject(toKeyValue: (item: T[0]) => [string, any]): Immutable; + flatMap(mapFunction: (item: T[0]) => TTarget): Immutable; } - type ImmutableObject = T & ImmutableObjectMixin; - type ImmutableArray = T[] & ImmutableArrayMixin; - type Immutable = ImmutableObject | ImmutableArray; + type BaseImmutable = (T extends any[] ? ImmutableArrayMixin : ImmutableObjectMixin) & T; - function from(obj: T[], options?: Options): ImmutableArray; - function from(obj: T, options?: Options): ImmutableObject; + type Immutable = { + readonly [P in keyof T]: T[P] extends object ? Immutable : T[P] + } & BaseImmutable; + + function from(obj: T, options?: Options): Immutable; function isImmutable(target: any): boolean; function ImmutableError(message: string): Error; - function replace(obj: ImmutableObject, valueObj: S, options?: ReplaceConfig): ImmutableObject; + function replace(obj: Immutable, valueObj: S, options?: ReplaceConfig): Immutable; } -declare function SeamlessImmutable(obj: T[], options?: SeamlessImmutable.Options): SeamlessImmutable.ImmutableArray; -declare function SeamlessImmutable(obj: T, options?: SeamlessImmutable.Options): SeamlessImmutable.ImmutableObject; +declare function SeamlessImmutable(obj: T, options?: SeamlessImmutable.Options): SeamlessImmutable.Immutable; diff --git a/types/seamless-immutable/seamless-immutable-tests.ts b/types/seamless-immutable/seamless-immutable-tests.ts index cccb2d7f96..54136f46db 100644 --- a/types/seamless-immutable/seamless-immutable-tests.ts +++ b/types/seamless-immutable/seamless-immutable-tests.ts @@ -25,13 +25,13 @@ interface ExtendedUser extends User { lastName: string; } - const arrayOfNumbers1: Immutable.ImmutableArray = Immutable.from([0, 2]); - const arrayOfNumbers2: Immutable.ImmutableArray = Immutable([0, 2]); - const user1: Immutable.ImmutableObject = Immutable.from({ + const arrayOfNumbers1: Immutable.Immutable = Immutable.from([0, 2]); + const arrayOfNumbers2: Immutable.Immutable = Immutable([0, 2]); + const user1: Immutable.Immutable = Immutable.from({ firstName: 'Angry', lastName: 'Monkey' }); - const user2: Immutable.ImmutableObject = Immutable({ + const user2: Immutable.Immutable = Immutable({ firstName: 'Angry', lastName: 'Monkey' }); @@ -44,7 +44,7 @@ interface ExtendedUser extends User { { const isImmutable: boolean = Immutable.isImmutable(Immutable.from([0, 2])); - const user1: Immutable.ImmutableObject = Immutable.from({ + const user1: Immutable.Immutable = Immutable.from({ firstName: 'Angry', lastName: 'Monkey' }); @@ -56,19 +56,23 @@ interface ExtendedUser extends User { // Instance syntax: immutable array // --------------------------------------------------------------- { - const array: Immutable.ImmutableArray = Immutable.from([ { firstName: 'Angry', lastName: 'Monkey' } ]); + const array: Immutable.Immutable = Immutable.from([ { firstName: 'Angry', lastName: 'Monkey' } ]); // asMutable const mutableArray1: User[] = array.asMutable(); const mutableArray2: User[] = array.asMutable({ deep: true }); // flatMap - const flatMappedArray: Immutable.ImmutableArray = array.flatMap((value: User) => + const flatMappedArray: Immutable.Immutable = array.flatMap((value: User) => [value, value] ); + const flatMappedArrayStrings: Immutable.Immutable = array.flatMap((value: User) => + value.firstName + ); + // asObject - const arrayToObject1: Immutable.ImmutableObject = array.asObject((value) => [value.toString(), value]); + const arrayToObject1: Immutable.Immutable = array.asObject((value) => [value.toString(), value]); } // @@ -76,11 +80,11 @@ interface ExtendedUser extends User { // --------------------------------------------------------------- { - const immutableUser: Immutable.ImmutableObject = Immutable.from({ + const immutableUser: Immutable.Immutable = Immutable.from({ firstName: 'Pure', lastName: 'Gold' }); - const immutableUserEx: Immutable.ImmutableObject = Immutable.from({ + const immutableUserEx: Immutable.Immutable = Immutable.from({ firstName: 'Hairy', lastName: 'Dog', address: { @@ -94,37 +98,37 @@ interface ExtendedUser extends User { }; // set: property name is strongly checked - const updatedUser01: Immutable.ImmutableObject = immutableUser.set('firstName', 'Whirlwind'); - const updatedUser02: Immutable.ImmutableObject = immutableUser.set(data.propertyId, 'Whirlwind'); + const updatedUser01: Immutable.Immutable = immutableUser.set('firstName', 'Whirlwind'); + const updatedUser02: Immutable.Immutable = immutableUser.set(data.propertyId, 'Whirlwind'); // setIn: property path is strongly checked for up to 5 arguments (helps with refactoring and intellisense) // but will fall back to any[] if there are dynamic arguments on the way - const updatedUser11: Immutable.ImmutableObject = immutableUserEx.setIn(['address', 'line1'], 'Small house'); - const updatedUser12: Immutable.ImmutableObject = immutableUserEx.setIn([ data.propertyId, 'line1' ], 'Small house'); + const updatedUser11: Immutable.Immutable = immutableUserEx.setIn(['address', 'line1'], 'Small house'); + const updatedUser12: Immutable.Immutable = immutableUserEx.setIn([ data.propertyId, 'line1' ], 'Small house'); // asMutable const mutableUser21: User = immutableUser.asMutable(); const mutableUser22: User = immutableUser.asMutable({ deep: true }); // merge: merged part is strongly checked as a deeply partial object - const mergedUser: Immutable.ImmutableObject = immutableUserEx.merge({ address: { line1: 'Small house' }, firstName: 'Jack' }); + const mergedUser: Immutable.Immutable = immutableUserEx.merge({ address: { line1: 'Small house' }, firstName: 'Jack' }); // update: property name is strongly checked - const updatedUser41: Immutable.ImmutableObject = immutableUser.update('firstName', x => x.toLowerCase() + ' Whirlwind'); + const updatedUser41: Immutable.Immutable = immutableUser.update('firstName', x => x.toLowerCase() + ' Whirlwind'); // the type of the updated value must be explicity specified in case of fallback - const updatedUser42: Immutable.ImmutableObject = immutableUser.update(data.propertyId, x => x.toLowerCase() + ' Whirlwind'); + const updatedUser42: Immutable.Immutable = immutableUser.update(data.propertyId, x => x.toLowerCase() + ' Whirlwind'); // updateIn: property path is strongly checked for up to 5 arguments (helps with refactoring and intellisense) // but will fall back to any[] if there are dynamic arguments on the way - const updatedUser51: Immutable.ImmutableObject = immutableUserEx.updateIn([ 'address', 'line1' ], x => x.toLowerCase() + ' 43'); + const updatedUser51: Immutable.Immutable = immutableUserEx.updateIn([ 'address', 'line1' ], x => x.toLowerCase() + ' 43'); // the type of the updated value must be explicity specified in case of fallback - const updatedUser52: Immutable.ImmutableObject = immutableUserEx.updateIn([ data.propertyId, 'line1' ], x => x.toLowerCase() + ' 43'); + const updatedUser52: Immutable.Immutable = immutableUserEx.updateIn([ data.propertyId, 'line1' ], x => x.toLowerCase() + ' 43'); // without - const simpleUser1: Immutable.ImmutableObject = immutableUserEx.without('address'); + const simpleUser1: Immutable.Immutable = immutableUserEx.without('address'); // getIn: propertyPath is strongly typed up to 5 parameters - const firstNameWithoutDefault = immutableUser.getIn(['firstName']); // infers Immutable + const firstNameWithoutDefault: string = immutableUser.getIn(['firstName']); // infers Immutable const firstNameWithDefault = immutableUser.getIn(['firstName'], ''); // infers Immutable const firstNameWithDynamicPathWithoutDefault = immutableUser.getIn(['first' + 'name']); const firstNameWithDynamicPathWithDefault = immutableUser.getIn(['first' + 'name'], '');