UNPKG

9.35 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 * A set of transformation to run as part of an evolve
178 * @param T - the type to be evolved
179 */
180export type Evolver<T extends Evolvable<any> = any> = {
181 // if T[K] isn't evolvable, don't allow nesting for that property
182 [key in keyof Partial<T>]: ((value: T[key]) => T[key]) | (T[key] extends Evolvable<any> ? Evolver<T[key]> : never);
183};
184
185/**
186 * <needs description>
187 * @param O
188 * @param E
189 */
190type EvolveNestedValue<O, E extends Evolver> =
191 O extends object
192 ? O extends Evolvable<E>
193 ? Evolve<O, E>
194 : never
195 : never;
196
197/**
198 * <needs description>
199 * @param V
200 * @param E
201 */
202type EvolveValue<V, E> =
203 E extends (value: V) => any
204 ? ReturnType<E>
205 : E extends Evolver
206 ? EvolveNestedValue<V, E>
207 : never;
208
209// ---------------------------------------------------------------------------------------
210// F
211
212/**
213 * <needs description>
214 */
215export interface Filter {
216 <T>(fn: (value: T) => boolean): FilterOnceApplied<T>;
217 <T, Kind extends 'array'>(fn: (value: T) => boolean): (list: readonly T[]) => T[];
218 <T, Kind extends 'object'>(fn: (value: T) => boolean): (list: Dictionary<T>) => Dictionary<T>;
219 <T>(fn: (value: T) => boolean, list: readonly T[]): T[];
220 <T>(fn: (value: T) => boolean, obj: Dictionary<T>): Dictionary<T>;
221}
222
223/**
224 * <needs description>
225 * @param A
226 */
227type FilterOnceApplied<A> =
228 <K extends A[] | Dictionary<A>>(source: K) =>
229 K extends Array<infer U>
230 ? U[]
231 : K extends Dictionary<infer U>
232 ? Dictionary<U>
233 : never;
234
235/**
236 * <needs description>
237 * @param A
238 */
239export interface Functor<A> {
240 map<U>(fn: (a: A) => U): Functor<U>;
241}
242
243// ---------------------------------------------------------------------------------------
244// K
245
246/**
247 * <needs description>
248 * @param K
249 * @param V
250 */
251export type KeyValuePair<K, V> = [K, V];
252
253// ---------------------------------------------------------------------------------------
254// L
255
256/**
257 * <needs description>
258 */
259export interface Lens {
260 <T, U>(obj: T): U;
261 set<T, U>(str: string, obj: T): U;
262}
263
264// ---------------------------------------------------------------------------------------
265// M
266
267/**
268 * Merge an object `O1` with `O2`
269 * @param O1
270 * @param O2
271 * @param Depth
272 *
273 * `O1` & `O2` are intersected with `[]` so that we can
274 * handle the scenario where we merge arrays (like ramda).
275 * Ramda removes array props when merging arrays, and thus
276 * only keeps own properties. This is what `ObjectOf` does.
277 *
278 * => ramda's `merge` functions are 100% properly typed.
279 *
280 * <created by @pirix-gh>
281 */
282export type Merge<O1 extends object, O2 extends object, Depth extends 'flat' | 'deep'> =
283 O.MergeUp<T.ObjectOf<O1>, T.ObjectOf<O2>, Depth>;
284
285/**
286 * Merge multiple objects `Os` with each other
287 * @param Os
288 *
289 * It essentially works like [[Merge]], since the utility
290 * `MergeUp` is used by `AssignUp` internally.
291 *
292 * <created by @pirix-gh>
293 */
294export type MergeAll<Os extends readonly object[]> =
295 O.AssignUp<{}, Os> extends infer M
296 ? {} extends M // nothing merged => bcs no `as const`
297 ? T.UnionOf<Os> // so we output the approximate types
298 : T.ObjectOf<M & {}> // otherwise, we can get accurate types
299 : never;
300
301// ---------------------------------------------------------------------------------------
302// O
303
304/**
305 * <needs description>
306 */
307export type ObjPred = (value: any, key: string) => boolean;
308
309/**
310 * <needs description>
311 */
312export type Ord = number | string | boolean | Date;
313
314// ---------------------------------------------------------------------------------------
315// P
316
317/**
318 * <needs description>
319 */
320export type Path = Array<(number | string)>;
321
322/**
323 * <needs description>
324 */
325export type Placeholder = A.x & {'@@functional/placeholder': true};
326
327/**
328 * <needs description>
329 */
330export type Pred = (...a: readonly any[]) => boolean;
331
332/**
333 * <needs description>
334 * @param V0
335 * @param R
336 */
337export type PipeWithFns<V0, R> = [
338 (x0: V0) => R
339] | [
340 (x0: V0) => any,
341 (x: any) => R
342] | [
343 (x0: V0) => any,
344 (x: any) => any,
345 (x: any) => R
346] | [
347 (x0: V0) => any,
348 (x: any) => any,
349 (x: any) => any,
350 (x: any) => R
351] | [
352 (x0: V0) => any,
353 (x: any) => any,
354 (x: any) => any,
355 (x: any) => any,
356 (x: any) => R
357] | [
358 (x0: V0) => any,
359 (x: any) => any,
360 (x: any) => any,
361 (x: any) => any,
362 (x: any) => any,
363 (x: any) => R
364] | [
365 (x0: V0) => any,
366 (x: any) => any,
367 (x: any) => any,
368 (x: any) => any,
369 (x: any) => any,
370 (x: any) => any,
371 (x: any) => R
372] | [
373 (x0: V0) => any,
374 (x: any) => any,
375 (x: any) => any,
376 (x: any) => any,
377 (x: any) => any,
378 (x: any) => any,
379 (x: any) => any,
380 (x: any) => R
381] | [
382 (x0: V0) => any,
383 (x: any) => any,
384 (x: any) => any,
385 (x: any) => any,
386 (x: any) => any,
387 (x: any) => any,
388 (x: any) => any,
389 (x: any) => any,
390 (x: any) => R
391] | [
392 (x0: V0) => 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) => any,
400 (x: any) => any,
401 (x: any) => R
402];
403
404// ---------------------------------------------------------------------------------------
405// R
406
407/**
408 * <needs description>
409 * @param A
410 */
411export interface Reduced<A> {
412 '@@transducer/value': A;
413 '@@transducer/reduced': true;
414}
415
416// ---------------------------------------------------------------------------------------
417// S
418
419/**
420 * <needs description>
421 * @param A
422 */
423export type SafePred<A> = (...a: readonly A[]) => boolean;
424
425// ---------------------------------------------------------------------------------------
426// V
427
428/**
429 * <needs description>
430 * @param R
431 */
432export type ValueOfRecord<R> =
433 R extends Record<any, infer T>
434 ? T
435 : never;
436
437export {};