-
Notifications
You must be signed in to change notification settings - Fork 14
/
utils.ts
121 lines (103 loc) · 2.92 KB
/
utils.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Minimum TypeScript Version: 3.4
// prettier-ignore
export type Functor<F, A, B> =
F extends A[] ? B[] :
F extends { [key: string]: A } ? { [key: string]: B } :
F extends Set<A> ? Set<B> :
F extends Map<infer K, A> ? Map<K, B> :
F extends Promise<A> ? Promise<B> :
never;
// prettier-ignore
export type Unpack<F> =
F extends Array<infer A> ? A :
F extends Set<infer A> ? A :
F extends Map<any, infer A> ? A :
F extends Promise<infer A> ? A :
F extends { [n: string]: infer A } ? A :
F extends { [n: number]: infer A } ? A :
F extends Record<string, infer A> ? A :
F extends Record<number, infer A> ? A :
F extends Record<symbol, infer A> ? A :
never;
export type HasKey<K extends string, V = any> =
| { [_ in K]: V }
| { [_ in K]?: V | undefined };
export interface ErrorCannotLensIntoOptionalKey<T, K> {
error: 'You have tried to lens through an optional key. Consider using `fill` to provide defaults to your object';
_val: T;
_key: K;
}
// prettier-ignore
export type KeyAt<T, K extends string> =
[T] extends [undefined] ? undefined:
[T] extends [null] ? null :
[T] extends [{ [_ in K]: any }] ? T[K] :
[T] extends [{ [_ in K]?: any }] ? T[K] :
ErrorCannotLensIntoOptionalKey<T, K>;
export type Collection<V, K = any> =
| V[]
| { [key: string]: V }
| Map<K, V>
| Set<V>;
export type Container<V, K = any> = Collection<V, K> | Promise<V>;
export type Indexable<V = any> = V[] | Map<number, V>;
export type Index<C> = C extends Indexable<infer V> ? V : never;
export type InputType<F, Return = any> = F extends (arg: infer A) => Return
? A
: never;
export type HasPattern<Pattern> = {
[K in keyof Pattern]:
| Pattern[K]
| InputType<Pattern[K]>
| (Pattern[K] extends (a: any) => any ? never : HasPattern<Pattern[K]>)
};
export type FillingPattern<Pattern> = {
[K in keyof Pattern]?: Pattern[K] | FillingPattern<Pattern[K]>
};
export type Fill<T extends FillingPattern<P>, P> = {
[K in Exclude<keyof T, keyof P>]: T[K]
} &
{ [K in keyof P]: P[K] };
export type Fn0<Out> = () => Out;
export type Fn1<A, Out> = (a: A) => Out;
export type Fn2<A, B, Out> = (a: A, b: B) => Out;
export type Fn3<A, B, C, Out> = (a: A, b: B, c: C) => Out;
export type Fn4<A, B, C, D, Out> = (a: A, b: B, c: C, d: D) => Out;
export type Fn5<A, B, C, D, E, Out> = (a: A, b: B, c: C, d: D, e: E) => Out;
export type Fn6<A, B, C, D, E, F, Out> = (
a: A,
b: B,
c: C,
d: D,
e: E,
f: F
) => Out;
export type Fn7<A, B, C, D, E, F, G, Out> = (
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G
) => Out;
export type Fn8<A, B, C, D, E, F, G, H, Out> = (
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H
) => Out;
export interface Traversal<Item> {
get(s: Collection<Item>): Collection<Item>;
mod(f: (a: Item) => Item): (s: Collection<Item>) => Collection<Item>;
traversal?: true;
}
export interface Lens<S, A> {
get(s: S): A;
mod(f: (a: A) => A): (s: S) => S;
traversal?: false;
}