From 1cae0b59f517da346d82e18abab8e6bae64e9fac Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 18 Aug 2024 21:44:55 +0000 Subject: [PATCH 1/2] Fix Map.sort and Set.sort TS return type --- package-lock.json | 14 ++-- package.json | 2 +- type-definitions/immutable.d.ts | 118 +++++++++++++++++++++++++++++++ type-definitions/ts-tests/map.ts | 25 ++++++- type-definitions/ts-tests/set.ts | 18 ++++- 5 files changed, 167 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b8be0457d..f350760544 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "rollup": "3.28.1", "size-limit": "^8.2.6", "transducers-js": "0.4.174", - "tstyche": "^2.0.0", + "tstyche": "^2.1.1", "typescript": "5.1" }, "engines": { @@ -11967,9 +11967,9 @@ } }, "node_modules/tstyche": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-2.0.0.tgz", - "integrity": "sha512-1LUCZEmMLRL7P0qDNtjx8oEEpU4qVUNggpsitl3XSGyuorbSNfees+EmMDC0VZ9FuClD0Far262U9oAT6Vz83Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-2.1.1.tgz", + "integrity": "sha512-SvAukLfHk894rbBJEu6+7S9ZggN89FDe4VA0xT/mldW7gmqcpmNV7+OghlR2IZyUbkas4mjrjOKxSWZ3IQzV+w==", "dev": true, "bin": { "tstyche": "build/bin.js" @@ -21366,9 +21366,9 @@ } }, "tstyche": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-2.0.0.tgz", - "integrity": "sha512-1LUCZEmMLRL7P0qDNtjx8oEEpU4qVUNggpsitl3XSGyuorbSNfees+EmMDC0VZ9FuClD0Far262U9oAT6Vz83Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-2.1.1.tgz", + "integrity": "sha512-SvAukLfHk894rbBJEu6+7S9ZggN89FDe4VA0xT/mldW7gmqcpmNV7+OghlR2IZyUbkas4mjrjOKxSWZ3IQzV+w==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 87b3f07950..58ae3eeb8e 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "rollup": "3.28.1", "size-limit": "^8.2.6", "transducers-js": "0.4.174", - "tstyche": "^2.0.0", + "tstyche": "^2.1.1", "typescript": "5.1" }, "size-limit": [ diff --git a/type-definitions/immutable.d.ts b/type-definitions/immutable.d.ts index d0d804dec4..dc6a4abd13 100644 --- a/type-definitions/immutable.d.ts +++ b/type-definitions/immutable.d.ts @@ -1591,6 +1591,65 @@ declare namespace Immutable { * @see Collection.Keyed.flip */ flip(): Map; + + /** + * Returns an OrderedMap of the same type which includes the same entries, + * stably sorted by using a `comparator`. + * + * If a `comparator` is not provided, a default comparator uses `<` and `>`. + * + * `comparator(valueA, valueB)`: + * + * * Returns `0` if the elements should not be swapped. + * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` + * * Returns `1` (or any positive number) if `valueA` comes after `valueB` + * * Alternatively, can return a value of the `PairSorting` enum type + * * Is pure, i.e. it must always return the same value for the same pair + * of values. + * + * + * ```js + * const { Map } = require('immutable') + * Map({ "c": 3, "a": 1, "b": 2 }).sort((a, b) => { + * if (a < b) { return -1; } + * if (a > b) { return 1; } + * if (a === b) { return 0; } + * }); + * // OrderedMap { "a": 1, "b": 2, "c": 3 } + * ``` + * + * Note: `sort()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sort(comparator?: Comparator): OrderedMap; + + /** + * Like `sort`, but also accepts a `comparatorValueMapper` which allows for + * sorting by more sophisticated means: + * + * + * ```js + * const { Map } = require('immutable') + * const beattles = Map({ + * John: { name: "Lennon" }, + * Paul: { name: "McCartney" }, + * George: { name: "Harrison" }, + * Ringo: { name: "Starr" }, + * }); + * beattles.sortBy(member => member.name); + * ``` + * + * Note: `sortBy()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sortBy( + comparatorValueMapper: (value: V, key: K, iter: this) => C, + comparator?: (valueA: C, valueB: C) => number + ): OrderedMap; } /** @@ -2012,6 +2071,65 @@ declare namespace Immutable { predicate: (this: C, value: T, key: T, iter: this) => unknown, context?: C ): [this, this]; + + /** + * Returns an OrderedSet of the same type which includes the same entries, + * stably sorted by using a `comparator`. + * + * If a `comparator` is not provided, a default comparator uses `<` and `>`. + * + * `comparator(valueA, valueB)`: + * + * * Returns `0` if the elements should not be swapped. + * * Returns `-1` (or any negative number) if `valueA` comes before `valueB` + * * Returns `1` (or any positive number) if `valueA` comes after `valueB` + * * Alternatively, can return a value of the `PairSorting` enum type + * * Is pure, i.e. it must always return the same value for the same pair + * of values. + * + * + * ```js + * const { Set } = require('immutable') + * Set(['b', 'a', 'c']).sort((a, b) => { + * if (a < b) { return -1; } + * if (a > b) { return 1; } + * if (a === b) { return 0; } + * }); + * // OrderedSet { "a":, "b", "c" } + * ``` + * + * Note: `sort()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sort(comparator?: Comparator): OrderedSet; + + /** + * Like `sort`, but also accepts a `comparatorValueMapper` which allows for + * sorting by more sophisticated means: + * + * + * ```js + * const { Set } = require('immutable') + * const beattles = Set([ + * { name: "Lennon" }, + * { name: "McCartney" }, + * { name: "Harrison" }, + * { name: "Starr" }, + * ]); + * beattles.sortBy(member => member.name); + * ``` + * + * Note: `sortBy()` Always returns a new instance, even if the original was + * already sorted. + * + * Note: This is always an eager operation. + */ + sortBy( + comparatorValueMapper: (value: T, key: T, iter: this) => C, + comparator?: (valueA: C, valueB: C) => number + ): OrderedSet; } /** diff --git a/type-definitions/ts-tests/map.ts b/type-definitions/ts-tests/map.ts index 249452badd..620421f9ce 100644 --- a/type-definitions/ts-tests/map.ts +++ b/type-definitions/ts-tests/map.ts @@ -1,5 +1,5 @@ import { expect, test } from 'tstyche'; -import { Map, List, MapOf } from 'immutable'; +import { Map, List, MapOf, OrderedMap } from 'immutable'; test('#constructor', () => { expect(Map()).type.toBe>(); @@ -602,6 +602,29 @@ test('#flip', () => { expect(Map().flip()).type.toBe>(); }); +test('#sort', () => { + expect(Map().sort()).type.toBe>(); + expect(Map().sort((a, b) => 1)).type.toBe< + OrderedMap + >(); + + expect(Map({ a: 'a' }).sort()).type.toBe>(); +}); + +test('#sortBy', () => { + expect(Map().sortBy(v => v)).type.toBe< + OrderedMap + >(); + + expect( + Map().sortBy( + v => v, + (a, b) => 1 + ) + ).type.toBe>(); + expect(Map({ a: 'a' }).sortBy(v => v)).type.toBe>(); +}); + test('#withMutations', () => { expect(Map().withMutations(mutable => mutable)).type.toBe< Map diff --git a/type-definitions/ts-tests/set.ts b/type-definitions/ts-tests/set.ts index 8bd565e42e..1b6f6d6008 100644 --- a/type-definitions/ts-tests/set.ts +++ b/type-definitions/ts-tests/set.ts @@ -1,5 +1,5 @@ import { expect, test } from 'tstyche'; -import { Set, Map, Collection } from 'immutable'; +import { Set, Map, Collection, OrderedSet } from 'immutable'; test('#constructor', () => { expect(Set()).type.toBe>(); @@ -229,6 +229,22 @@ test('#flatten', () => { expect(Set().flatten('a')).type.toRaiseError(); }); +test('#sort', () => { + expect(Set().sort()).type.toBe>(); + expect(Set().sort((a, b) => 1)).type.toBe>(); +}); + +test('#sortBy', () => { + expect(Set().sortBy(v => v)).type.toBe>(); + + expect( + Set().sortBy( + v => v, + (a, b) => 1 + ) + ).type.toBe>(); +}); + test('#withMutations', () => { expect(Set().withMutations(mutable => mutable)).type.toBe< Set From 1099ba1298b8d58d8d1827476190ac7217d41ee0 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Mon, 19 Aug 2024 08:35:19 +0000 Subject: [PATCH 2/2] Fix inheritance problem with `this` --- type-definitions/immutable.d.ts | 8 ++++---- type-definitions/ts-tests/map.ts | 18 ++++++++++++------ type-definitions/ts-tests/set.ts | 12 ++++++++---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/type-definitions/immutable.d.ts b/type-definitions/immutable.d.ts index dc6a4abd13..b27aac2a74 100644 --- a/type-definitions/immutable.d.ts +++ b/type-definitions/immutable.d.ts @@ -1623,7 +1623,7 @@ declare namespace Immutable { * * Note: This is always an eager operation. */ - sort(comparator?: Comparator): OrderedMap; + sort(comparator?: Comparator): this & OrderedMap; /** * Like `sort`, but also accepts a `comparatorValueMapper` which allows for @@ -1649,7 +1649,7 @@ declare namespace Immutable { sortBy( comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number - ): OrderedMap; + ): this & OrderedMap; } /** @@ -2103,7 +2103,7 @@ declare namespace Immutable { * * Note: This is always an eager operation. */ - sort(comparator?: Comparator): OrderedSet; + sort(comparator?: Comparator): this & OrderedSet; /** * Like `sort`, but also accepts a `comparatorValueMapper` which allows for @@ -2129,7 +2129,7 @@ declare namespace Immutable { sortBy( comparatorValueMapper: (value: T, key: T, iter: this) => C, comparator?: (valueA: C, valueB: C) => number - ): OrderedSet; + ): this & OrderedSet; } /** diff --git a/type-definitions/ts-tests/map.ts b/type-definitions/ts-tests/map.ts index 620421f9ce..aa62cf2710 100644 --- a/type-definitions/ts-tests/map.ts +++ b/type-definitions/ts-tests/map.ts @@ -603,17 +603,21 @@ test('#flip', () => { }); test('#sort', () => { - expect(Map().sort()).type.toBe>(); + expect(Map().sort()).type.toBe< + Map & OrderedMap + >(); expect(Map().sort((a, b) => 1)).type.toBe< - OrderedMap + Map & OrderedMap >(); - expect(Map({ a: 'a' }).sort()).type.toBe>(); + expect(Map({ a: 'a' }).sort()).type.toBe< + MapOf<{ a: string }> & OrderedMap<'a', string> + >(); }); test('#sortBy', () => { expect(Map().sortBy(v => v)).type.toBe< - OrderedMap + Map & OrderedMap >(); expect( @@ -621,8 +625,10 @@ test('#sortBy', () => { v => v, (a, b) => 1 ) - ).type.toBe>(); - expect(Map({ a: 'a' }).sortBy(v => v)).type.toBe>(); + ).type.toBe & OrderedMap>(); + expect(Map({ a: 'a' }).sortBy(v => v)).type.toBe< + MapOf<{ a: string }> & OrderedMap<'a', string> + >(); }); test('#withMutations', () => { diff --git a/type-definitions/ts-tests/set.ts b/type-definitions/ts-tests/set.ts index 1b6f6d6008..c3183a4b0c 100644 --- a/type-definitions/ts-tests/set.ts +++ b/type-definitions/ts-tests/set.ts @@ -230,19 +230,23 @@ test('#flatten', () => { }); test('#sort', () => { - expect(Set().sort()).type.toBe>(); - expect(Set().sort((a, b) => 1)).type.toBe>(); + expect(Set().sort()).type.toBe & OrderedSet>(); + expect(Set().sort((a, b) => 1)).type.toBe< + Set & OrderedSet + >(); }); test('#sortBy', () => { - expect(Set().sortBy(v => v)).type.toBe>(); + expect(Set().sortBy(v => v)).type.toBe< + Set & OrderedSet + >(); expect( Set().sortBy( v => v, (a, b) => 1 ) - ).type.toBe>(); + ).type.toBe & OrderedSet>(); }); test('#withMutations', () => {