8000 Migrate functional files to TS (#2063) · immutable-js/immutable-js@70826e6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 70826e6

Browse files
authored
Migrate functional files to TS (#2063)
* Migrate functional files to TS * migrate some TS types in type-definition file * update / updateIn * setIn / removeIn
1 parent 5b932ce commit 70826e6

File tree

18 files changed

+600
-161
lines changed

18 files changed

+600
-161
lines changed

__tests__/updateIn.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,17 @@ describe('updateIn', () => {
109109

110110
// code that works perfectly
111111
expect(
112-
// @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection<K> | ArrayLike<K>;
113-
updateIn({ 10: { 20: 'a' } }, customArray, (v) => `${v.toUpperCase()}`)
112+
updateIn({ 10: { 20: 'a' } }, customArray, (v) =>
113+
// @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection<K> | ArrayLike<K>;
114+
typeof v === 'string' ? v.toUpperCase() : v
115+
)
114116
).toEqual({ 10: { 20: 'A' } });
115117

116118
expect(() =>
117-
// @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection<K> | ArrayLike<K>;
118-
updateIn({ 10: 'a' }, customArray, (v) => `${v.toUpperCase()}`)
119+
updateIn({ 10: 'a' }, customArray, (v) =>
120+
// @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection<K> | ArrayLike<K>;
121+
typeof v === 'string' ? v.toUpperCase() : v
122+
)
119123
).toThrow('Cannot update within non-data-structure value in path [10]: a');
120124
});
121125

src/functional/get.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import { has } from './has';
1111
*
1212
* <!-- runkit:activate -->
1313
* ```js
14-
* const { get } = require('immutable')
14+
* import { get } from 'immutable';
15+
*
1516
* g 2364 et([ 'dog', 'frog', 'cat' ], 1) // 'frog'
1617
* get({ x: 123, y: 456 }, 'x') // 123
1718
* get({ x: 123, y: 456 }, 'z', 'ifNotSet') // 'ifNotSet'
@@ -48,6 +49,11 @@ export function get<V, NSV>(
4849
key: string,
4950
notSetValue: NSV
5051
): V | NSV;
52+
export function get<K extends PropertyKey, V, NSV>(
53+
collection: Collection<K, V> | Array<V> | { [key: string]: V },
54+
key: K,
55+
notSetValue?: NSV
56+
): V | NSV;
5157
export function get<K extends PropertyKey, V, NSV>(
5258
collection: Collection<K, V> | Array<V> | { [key: string]: V },
5359
key: K,

src/functional/getIn.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
11
import coerceKeyPath from '../utils/coerceKeyPath';
22
import { NOT_SET } from '../TrieUtils';
33
import { get } from './get';
4-
import type { OrderedCollection } from '../../type-definitions/immutable';
4+
import type { KeyPath } from '../../type-definitions/immutable';
55

66
type GetType = typeof get;
77
type GetTypeParameters = Parameters<GetType>;
88
type CollectionType = GetTypeParameters[0];
99
type Key = GetTypeParameters[1];
1010

11+
/**
12+
* Returns the value at the provided key path starting at the provided
13+
* collection, or notSetValue if the key path is not defined.
14+
*
15+
* A functional alternative to `collection.getIn(keypath)` which will also
16+
* work with plain Objects and Arrays.
17+
*
18+
* <!-- runkit:activate -->
19+
* ```js
20+
* import { getIn } from 'immutable';
21+
*
22+
* getIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // 123
23+
* getIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p'], 'ifNotSet') // 'ifNotSet'
24+
* ```
25+
*/
1126
export function getIn(
1227
collection: CollectionType,
13-
searchKeyPath: OrderedCollection<Key> | ArrayLike<Key>,
28+
searchKeyPath: KeyPath<Key>,
1429
notSetValue?: GetTypeParameters[2]
1530
): ReturnType<GetType> {
1631
const keyPath = coerceKeyPath(searchKeyPath);

src/functional/has.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,27 @@ import { isImmutable } from '../predicates/isImmutable';
22
import hasOwnProperty from '../utils/hasOwnProperty';
33
import isDataStructure from '../utils/isDataStructure';
44

5-
export function has(collection: object, key: PropertyKey): boolean {
5+
/**
6+
* Returns true if the key is defined in the provided collection.
7+
*
8+
* A functional alternative to `collection.has(key)` which will also work with
9+
* plain Objects and Arrays as an alternative for
10+
* `collection.hasOwnProperty(key)`.
11+
*
12+
* <!-- runkit:activate -->
13+
* ```js
14+
* import { has } from 'immutable';
15+
*
16+
* has([ 'dog', 'frog', 'cat' ], 2) // true
17+
* has([ 'dog', 'frog', 'cat' ], 5) // false
18+
* has({ x: 123, y: 456 }, 'x') // true
19+
* has({ x: 123, y: 456 }, 'z') // false
20+
* ```
21+
*/
22+
export function has(collection: object, key: unknown): boolean {
623
return isImmutable(collection)
724
? // @ts-expect-error key might be a number or symbol, which is not handled be Record key type
825
collection.has(key)
9-
: isDataStructure(collection) && hasOwnProperty.call(collection, key);
26+
: // @ts-expect-error key might be anything else than PropertyKey, and will return false in that case but runtime is OK
27+
isDataStructure(collection) && hasOwnProperty.call(collection, key);
1028
}

src/functional/hasIn.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@ import { NOT_SET } from '../TrieUtils';
33

44
type GetInParameters = Parameters<typeof getIn>;
55

6+
/**
7+
* Returns true if the key path is defined in the provided collection.
8+
*
9+
* A functional alternative to `collection.hasIn(keypath)` which will also
10+
* work with plain Objects and Arrays.
11+
*
12+
* <!-- runkit:activate -->
13+
* ```js
14+
* import { hasIn } from 'immutable';
15+
*
16+
* hasIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // true
17+
* hasIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p']) // false
18+
* ```
19+
*/
620
export function hasIn(
721
collection: GetInParameters[0],
822
keyPath: GetInParameters[1]

src/functional/remove.js

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/functional/remove.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import type { Collection, Record } from '../../type-definitions/immutable';
2+
import { isImmutable } from '../predicates/isImmutable';
3+
import hasOwnProperty from '../utils/hasOwnProperty';
4+
import isDataStructure from '../utils/isDataStructure';
5+
import shallowCopy from '../utils/shallowCopy';
6+
7+
/**
8+
* Returns a copy of the collection with the value at key removed.
9+
*
10+
* A functional alternative to `collection.remove(key)` which will also work
11+
* with plain Objects and Arrays as an alternative for
12+
* `delete collectionCopy[key]`.
13+
*
14+
* <!-- runkit:activate -->
15+
* ```js
16+
* import { remove } from 'immutable';
17+
*
18+
* const originalArray = [ 'dog', 'frog', 'cat' ]
19+
* remove(originalArray, 1) // [ 'dog', 'cat' ]
20+
* console.log(originalArray) // [ 'dog', 'frog', 'cat' ]
21+
* const originalObject = { x: 123, y: 456 }
22+
* remove(originalObject, 'x') // { y: 456 }
23+
* console.log(originalObject) // { x: 123, y: 456 }
24+
* ```
25+
*/
26+
export function remove<K, C extends Collection<K, unknown>>(
27+
collection: C,
28+
key: K
29+
): C;
30+
export function remove<
31+
TProps extend B41A s object,
32+
C extends Record<TProps>,
33+
K extends keyof TProps,
34+
>(collection: C, key: K): C;
35+
export function remove<C extends Array<unknown>>(collection: C, key: number): C;
36+
export function remove<C, K extends keyof C>(collection: C, key: K): C;
37+
export function remove<
38+
C extends { [key: PropertyKey]: unknown },
39+
K extends keyof C,
40+
>(collection: C, key: K): C;
41+
export function remove<
42+
K extends PropertyKey,
43+
C extends
44+
| Collection<K, unknown>
45+
| Array<unknown>
46+
| { [key: PropertyKey]: unknown },
47+
>(collection: C, key: K): C;
48+
export function remove<K extends PropertyKey>(
49+
collection:
50+
| Collection<K, unknown>
51+
| Array<unknown>
52+
| { [key: PropertyKey]: unknown },
53+
key: K
54+
) {
55+
if (!isDataStructure(collection)) {
56+
throw new TypeError(
57+
'Cannot update non-data-structure value: ' + collection
58+
);
59+
}
60+
if (isImmutable(collection F438 )) {
61+
// @ts-expect-error weird "remove" here,
62+
if (!collection.remove) {
63+
throw new TypeError(
64+
'Cannot update immutable value without .remove() method: ' + collection
65+
);
66+
}
67+
// @ts-expect-error weird "remove" here,
68+
return collection.remove(key);
69+
}
70+
if (!hasOwnProperty.call(collection, key)) {
71+
return collection;
72+
}
73+
const collectionCopy = shallowCopy(collection);
74+
if (Array.isArray(collectionCopy)) {
75+
// @ts-expect-error assert that key is a number here
76+
collectionCopy.splice(key, 1);
77+
} else {
78+
delete collectionCopy[key];
79+
}
80+
return collectionCopy;
81+
}

src/functional/removeIn.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/functional/removeIn.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { updateIn, type PossibleCollection } from './updateIn';
2+
import { NOT_SET } from '../TrieUtils';
3+
import type { KeyPath } from '../../type-definitions/immutable';
4+
5+
/**
6+
* Returns a copy of the collection with the value at the key path removed.
7+
*
8+
* A functional alternative to `collection.removeIn(keypath)` which will also
9+
* work with plain Objects and Arrays.
10+
*
11+
* <!-- runkit:activate -->
12+
* ```js
13+
* import { removeIn } from 'immutable';
14+
*
15+
* const original = { x: { y: { z: 123 }}}
16+
* removeIn(original, ['x', 'y', 'z']) // { x: { y: {}}}
17+
* console.log(original) // { x: { y: { z: 123 }}}
18+
* ```
19+
*/
20+
export function removeIn<
21+
K extends PropertyKey,
22+
V,
23+
TProps extends object,
24+
C extends PossibleCollection<K, V, TProps>,
25+
>(collection: C, keyPath: KeyPath<K>): C {
26+
return updateIn(collection, keyPath, () => NOT_SET);
27+
}

src/functional/set.js

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/functional/set.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import type { Collection, Record } from '../../type-definitions/immutable';
2+
import { isImmutable } from '../predicates/isImmutable';
3+
import hasOwnProperty from '../utils/hasOwnProperty';
4+
import isDataStructure from '../utils/isDataStructure';
5+
import shallowCopy from '../utils/shallowCopy';
6+
7+
/**
8+
* Returns a copy of the collection with the value at key set to the provided
9+
* value.
10+
*
11+
* A functional alternative to `collection.set(key, value)` which will also
12+
* work with plain Objects and Arrays as an alternative for
13+
* `collectionCopy[key] = value`.
14+
*
15+
* <!-- runkit:activate -->
16+
* ```js
17+
* import { set } from 'immutable';
18+
*
19+
* const originalArray = [ 'dog', 'frog', 'cat' ]
20+
* set(originalArray, 1, 'cow') // [ 'dog', 'cow', 'cat' ]
21+
* console.log(originalArray) // [ 'dog', 'frog', 'cat' ]
22+
* const originalObject = { x: 123, y: 456 }
23+
* set(originalObject, 'x', 789) // { x: 789, y: 456 }
24+
* console.log(originalObject) // { x: 123, y: 456 }
25+
* ```
26+
*/
27+
export function set<K, V, C extends Collection<K, V>>(
28+
collection: C,
29+
key: K,
30+
value: V
31+
): C;
32+
export function set<
33+
TProps extends object,
34+
C extends Record<TProps>,
35+
K extends keyof TProps,
36+
>(record: C, key: K, value: TProps[K]): C;
37+
export function set<V, C extends Array<V>>(
38+
collection: C,
39+
key: number,
40+
value: V
41+
): C;
42+
export function set<C, K extends keyof C>(object: C, key: K, value: C[K]): C;
43+
export function set<V, C extends { [key: string]: V }>(
44+
collection: C,
45+
key: string,
46+
value: V
47+
): C;
48+
export function set<K, V, C extends Collection<K, V> | { [key: string]: V }>(
49+
collection: C,
50+
key: K | string,
51+
value: V
52+
): C {
53+
if (!isDataStructure(collection)) {
54+
throw new TypeError(
55+
'Cannot update non-data-structure value: ' + collection
56+
);
57+
}
58+
if (isImmutable(collection)) {
59+
// @ts-expect-error weird "set" here,
60+
if (!collection.set) {
61+
throw new TypeError(
62+
'Cannot update immutable value without .set() method: ' + collection
63+
);
64+
}
65+
// @ts-expect-error weird "set" here,
66+
return collection.set(key, value);
67+
}
68+
// @ts-expect-error mix of key and string here. Probably need a more fine type here
69+
if (hasOwnProperty.call(collection, key) && value === collection[key]) {
70+
return collection;
71+
}
72+
const collectionCopy = shallowCopy(collection);
73+
// @ts-expect-error mix of key and string here. Probably need a more fine type here
74+
collectionCopy[key] = value;
75+
return collectionCopy;
76+
}

src/functional/setIn.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0