-
Notifications
You must be signed in to change notification settings - Fork 26
/
index.d.ts
46 lines (45 loc) · 2.11 KB
/
index.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { Head, Tail, Includes, Unshift, Reverse } from '..';
// Removes all given values from an array: https://lodash.com/docs/4.17.15#nth.
//
type S = Pull<[1, 2, 3], [2]>; // [1, 3]
//
// This type uses recursive (and not officially supported) type alias, see more:
// https://github.com/microsoft/TypeScript/issues/26223#issuecomment-513187373.
export type Pull<
// The input array.
T extends Array<any>,
// The values to remove.
D extends Array<any>,
// An internal array to accumulate the result.
R extends Array<any> = []
> = {
// If the input array is empty then we reached the end of our recursion and we just
// return the accumulated result. We `Reverse` the it before returning since we keep
// unshifting elements into it.
finish: Reverse<R>;
// Then, check if the next value in the input array is in the array of values to remove.
// If it is then we should exclude it from our accumulator and we just run the recursion
// again on the rest of the input array (skipping this value and not adding it to the
// accumulator):
skip: Pull<Tail<T>, D, R>;
// Finally, if it's not in the array of values to remove, we add the next value of `T`
// into the accumulator and run the recursion again on the rest of the input array:
insert: Pull<Tail<T>, D, Unshift<R, Head<T>>>;
// For example, Pull<[1, 2, 3], [2]> will first translate into: Pull<[2, 3], [2], [1]>.
// Notice that the first element of the array was inserted into the accumulator (3rd
// argument) because it's not present in the array of values to removes ([2]).
//
// Next, the recursion will be called again: Pull<[3], [2], [1]>. Since the next value
// of the array (2) is in the array of values to remove, we don't insert it inot the
// accumulator, and the recursion runs on the rest of the array.
//
// Then, the recursion runs again with Pull<[], [2], [3, 1]> since 3 isn't in the array
// of values to remove.
//
// And finally, since the array is now empty, pull returns the reversed accumulated value
// which is [1, 3].
}[T extends []
? 'finish'
: Includes<D, Head<T>> extends true
? 'skip'
: 'insert'];