UNPKG

9.12 kBTypeScriptView Raw
1import { A, O, T } from "ts-toolbelt";
2
3// ///////////////////////////////////////////////////////////////////////////////////////
4// TOOLS /////////////////////////////////////////////////////////////////////////////////
5
6// Here lies a loose collection of tools that compute types for the functions in "index.d.ts"
7// The goal of this file is to keep "index.d.ts" readable as well as hiding implementations
8
9// WHEN ADDING A NEW TOOL
10// - Add documentation for the tool you've created
11// - Add <created by @username> on your tool's docs
12
13// TODO
14// - Types need proper descriptions, so that we know what they do
15
16// ---------------------------------------------------------------------------------------
17// A
18
19/**
20 * <needs description>
21 */
22export type Arity0Fn = () => any;
23
24/**
25 * <needs description>
26 */
27export type Arity1Fn = (a: any) => any;
28
29/**
30 * <needs description>
31 */
32export type Arity2Fn = (a: any, b: any) => any;
33
34/**
35 * <needs description>
36 */
37export interface ArrayLike {
38 nodeType: number;
39}
40
41/**
42 * <needs description>
43 * @param K
44 */
45export interface AssocPartialOne<K extends keyof any> {
46 <T>(val: T): <U>(obj: U) => Record<K, T> & U;
47 <T, U>(val: T, obj: U): Record<K, T> & U;
48}
49
50// ---------------------------------------------------------------------------------------
51// C
52
53/**
54 * <needs description>
55 */
56export interface CharList extends String {
57 push(x: string): void;
58}
59
60/**
61 * <needs description>
62 * @param V0
63 * @param R
64 */
65export type ComposeWithFns<V0, R> = [
66 (x0: V0) => R
67] | [
68 (x: any) => R,
69 (x: V0) => any
70] | [
71 (x: any) => R,
72 (x: any) => any,
73 (x: V0) => any
74] | [
75 (x: any) => R,
76 (x: any) => any,
77 (x: any) => any,
78 (x: V0) => any
79] | [
80 (x: any) => R,
81 (x: any) => any,
82 (x: any) => any,
83 (x: any) => any,
84 (x: V0) => any
85] | [
86 (x: any) => R,
87 (x: any) => any,
88 (x: any) => any,
89 (x: any) => any,
90 (x: any) => any,
91 (x: V0) => any
92] | [
93 (x: any) => R,
94 (x: any) => any,
95 (x: any) => any,
96 (x: any) => any,
97 (x: any) => any,
98 (x: any) => any,
99 (x: V0) => any
100] | [
101 (x: any) => R,
102 (x: any) => any,
103 (x: any) => any,
104 (x: any) => any,
105 (x: any) => any,
106 (x: any) => any,
107 (x: any) => any,
108 (x: V0) => any
109] | [
110 (x: any) => R,
111 (x: any) => any,
112 (x: any) => any,
113 (x: any) => any,
114 (x: any) => any,
115 (x: any) => any,
116 (x: any) => any,
117 (x: any) => any,
118 (x: V0) => any
119] | [
120 (x: any) => R,
121 (x: any) => any,
122 (x: any) => any,
123 (x: any) => any,
124 (x: any) => any,
125 (x: any) => any,
126 (x: any) => any,
127 (x: any) => any,
128 (x: any) => any,
129 (x: V0) => any
130];
131
132// ---------------------------------------------------------------------------------------
133// D
134
135/**
136 * <needs description>
137 * @param A
138 */
139export interface Dictionary<A> {
140 [index: string]: A;
141}
142
143// ---------------------------------------------------------------------------------------
144// E
145
146/**
147 * Represents all objects evolvable with Evolver E
148 * @param E
149 */
150export type Evolvable<E extends Evolver> = {
151 [P in keyof E]?: Evolved<E[P]>;
152};
153
154/**
155 * <needs description>
156 * @param O
157 * @param E
158 */
159export type Evolve<O extends Evolvable<E>, E extends Evolver> = {
160 [P in keyof O]: P extends keyof E
161 ? EvolveValue<O[P], E[P]>
162 : O[P];
163};
164
165/**
166 * <needs description>
167 * @param A
168 */
169type Evolved<A> =
170 A extends (value: infer V) => any
171 ? V
172 : A extends Evolver
173 ? Evolvable<A>
174 : never;
175
176/**
177 * <needs description>
178 */
179export interface Evolver {
180 [key: string]: ((value: any) => any) | Evolver;
181}
182
183/**
184 * <needs description>
185 * @param O
186 * @param E
187 */
188type EvolveNestedValue<O, E extends Evolver> =
189 O extends object
190 ? O extends Evolvable<E>
191 ? Evolve<O, E>
192 : never
193 : never;
194
195/**
196 * <needs description>
197 * @param V
198 * @param E
199 */
200type EvolveValue<V, E> =
201 E extends (value: V) => any
202 ? ReturnType<E>
203 : E extends Evolver
204 ? EvolveNestedValue<V, E>
205 : never;
206
207// ---------------------------------------------------------------------------------------
208// F
209
210/**
211 * <needs description>
212 */
213export interface Filter {
214 <T>(fn: (value: T) => boolean): FilterOnceApplied<T>;
215 <T, Kind extends 'array'>(fn: (value: T) => boolean): (list: readonly T[]) => T[];
216 <T, Kind extends 'object'>(fn: (value: T) => boolean): (list: Dictionary<T>) => Dictionary<T>;
217 <T>(fn: (value: T) => boolean, list: readonly T[]): T[];
218 <T>(fn: (value: T) => boolean, obj: Dictionary<T>): Dictionary<T>;
219}
220
221/**
222 * <needs description>
223 * @param A
224 */
225type FilterOnceApplied<A> =
226 <K extends A[] | Dictionary<A>>(source: K) =>
227 K extends Array<infer U>
228 ? U[]
229 : K extends Dictionary<infer U>
230 ? Dictionary<U>
231 : never;
232
233/**
234 * <needs description>
235 * @param A
236 */
237export interface Functor<A> {
238 map<U>(fn: (a: A) => U): Functor<U>;
239}
240
241// ---------------------------------------------------------------------------------------
242// K
243
244/**
245 * <needs description>
246 * @param K
247 * @param V
248 */
249export type KeyValuePair<K, V> = [K, V];
250
251// ---------------------------------------------------------------------------------------
252// L
253
254/**
255 * <needs description>
256 */
257export interface Lens {
258 <T, U>(obj: T): U;
259 set<T, U>(str: string, obj: T): U;
260}
261
262// ---------------------------------------------------------------------------------------
263// M
264
265/**
266 * Merge an object `O1` with `O2`
267 * @param O1
268 * @param O2
269 * @param Depth
270 *
271 * `O1` & `O2` are intersected with `[]` so that we can
272 * handle the scenario where we merge arrays (like ramda).
273 * Ramda removes array props when merging arrays, and thus
274 * only keeps own properties. This is what `ObjectOf` does.
275 *
276 * => ramda's `merge` functions are 100% properly typed.
277 *
278 * <created by @pirix-gh>
279 */
280export type Merge<O1 extends object, O2 extends object, Depth extends 'flat' | 'deep'> =
281 O.MergeUp<T.ObjectOf<O1>, T.ObjectOf<O2>, Depth>;
282
283/**
284 * Merge multiple objects `Os` with each other
285 * @param Os
286 *
287 * It essentially works like [[Merge]], since the utility
288 * `MergeUp` is used by `AssignUp` internally.
289 *
290 * <created by @pirix-gh>
291 */
292export type MergeAll<Os extends readonly object[]> =
293 O.AssignUp<{}, Os> extends infer M
294 ? {} extends M // nothing merged => bcs no `as const`
295 ? T.UnionOf<Os> // so we output the approximate types
296 : T.ObjectOf<M & {}> // otherwise, we can get accurate types
297 : never;
298
299// ---------------------------------------------------------------------------------------
300// O
301
302/**
303 * <needs description>
304 */
305export type ObjPred = (value: any, key: string) => boolean;
306
307/**
308 * <needs description>
309 */
310export type Ord = number | string | boolean | Date;
311
312// ---------------------------------------------------------------------------------------
313// P
314
315/**
316 * <needs description>
317 */
318export type Path = Array<(number | string)>;
319
320/**
321 * <needs description>
322 */
323export type Placeholder = A.x & {'@@functional/placeholder': true};
324
325/**
326 * <needs description>
327 */
328export type Pred = (...a: readonly any[]) => boolean;
329
330/**
331 * <needs description>
332 * @param V0
333 * @param R
334 */
335export type PipeWithFns<V0, R> = [
336 (x0: V0) => R
337] | [
338 (x0: V0) => any,
339 (x: any) => R
340] | [
341 (x0: V0) => any,
342 (x: any) => any,
343 (x: any) => R
344] | [
345 (x0: V0) => any,
346 (x: any) => any,
347 (x: any) => any,
348 (x: any) => R
349] | [
350 (x0: V0) => any,
351 (x: any) => any,
352 (x: any) => any,
353 (x: any) => any,
354 (x: any) => R
355] | [
356 (x0: V0) => any,
357 (x: any) => any,
358 (x: any) => any,
359 (x: any) => any,
360 (x: any) => any,
361 (x: any) => R
362] | [
363 (x0: V0) => any,
364 (x: any) => any,
365 (x: any) => any,
366 (x: any) => any,
367 (x: any) => any,
368 (x: any) => any,
369 (x: any) => R
370] | [
371 (x0: V0) => any,
372 (x: any) => any,
373 (x: any) => any,
374 (x: any) => any,
375 (x: any) => any,
376 (x: any) => any,
377 (x: any) => any,
378 (x: any) => R
379] | [
380 (x0: V0) => any,
381 (x: any) => any,
382 (x: any) => any,
383 (x: any) => any,
384 (x: any) => any,
385 (x: any) => any,
386 (x: any) => any,
387 (x: any) => any,
388 (x: any) => R
389] | [
390 (x0: V0) => any,
391 (x: any) => any,
392 (x: any) => any,
393 (x: any) => any,
394 (x: any) => any,
395 (x: any) => any,
396 (x: any) => any,
397 (x: any) => any,
398 (x: any) => any,
399 (x: any) => R
400];
401
402// ---------------------------------------------------------------------------------------
403// R
404
405/**
406 * <needs description>
407 * @param A
408 */
409export interface Reduced<A> {
410 '@@transducer/value': A;
411 '@@transducer/reduced': true;
412}
413
414// ---------------------------------------------------------------------------------------
415// S
416
417/**
418 * <needs description>
419 * @param A
420 */
421export type SafePred<A> = (...a: readonly A[]) => boolean;
422
423// ---------------------------------------------------------------------------------------
424// V
425
426/**
427 * <needs description>
428 * @param R
429 */
430export type ValueOfRecord<R> =
431 R extends Record<any, infer T>
432 ? T
433 : never;
434
435export {};