1
- type Func0 < R > = ( ) => R
2
- type Func1 < T1 , R > = ( a1 : T1 ) => R
3
- type Func2 < T1 , T2 , R > = ( a1 : T1 , a2 : T2 ) => R
4
- type Func3 < T1 , T2 , T3 , R > = ( a1 : T1 , a2 : T2 , a3 : T3 , ...args : any [ ] ) => R
1
+ import { F , T } from 'ts-toolbelt'
5
2
6
3
/**
7
4
* Composes single-argument functions from right to left. The rightmost
@@ -13,85 +10,15 @@ type Func3<T1, T2, T3, R> = (a1: T1, a2: T2, a3: T3, ...args: any[]) => R
13
10
* to left. For example, `compose(f, g, h)` is identical to doing
14
11
* `(...args) => f(g(h(...args)))`.
15
12
*/
16
- export default function compose ( ) : < R > ( a : R ) => R
17
-
18
- export default function compose < F extends Function > ( f : F ) : F
19
-
20
- /* two functions */
21
- export default function compose < A , R > ( f1 : ( b : A ) => R , f2 : Func0 < A > ) : Func0 < R >
22
- export default function compose < A , T1 , R > (
23
- f1 : ( b : A ) => R ,
24
- f2 : Func1 < T1 , A >
25
- ) : Func1 < T1 , R >
26
- export default function compose < A , T1 , T2 , R > (
27
- f1 : ( b : A ) => R ,
28
- f2 : Func2 < T1 , T2 , A >
29
- ) : Func2 < T1 , T2 , R >
30
- export default function compose < A , T1 , T2 , T3 , R > (
31
- f1 : ( b : A ) => R ,
32
- f2 : Func3 < T1 , T2 , T3 , A >
33
- ) : Func3 < T1 , T2 , T3 , R >
34
-
35
- /* three functions */
36
- export default function compose < A , B , R > (
37
- f1 : ( b : B ) => R ,
38
- f2 : ( a : A ) => B ,
39
- f3 : Func0 < A >
40
- ) : Func0 < R >
41
- export default function compose < A , B , T1 , R > (
42
- f1 : ( b : B ) => R ,
43
- f2 : ( a : A ) => B ,
44
- f3 : Func1 < T1 , A >
45
- ) : Func1 < T1 , R >
46
- export default function compose < A , B , T1 , T2 , R > (
47
- f1 : ( b : B ) => R ,
48
- f2 : ( a : A ) => B ,
49
- f3 : Func2 < T1 , T2 , A >
50
- ) : Func2 < T1 , T2 , R >
51
- export default function compose < A , B , T1 , T2 , T3 , R > (
52
- f1 : ( b : B ) => R ,
53
- f2 : ( a : A ) => B ,
54
- f3 : Func3 < T1 , T2 , T3 , A >
55
- ) : Func3 < T1 , T2 , T3 , R >
56
-
57
- /* four functions */
58
- export default function compose < A , B , C , R > (
59
- f1 : ( b : C ) => R ,
60
- f2 : ( a : B ) => C ,
61
- f3 : ( a : A ) => B ,
62
- f4 : Func0 < A >
63
- ) : Func0 < R >
64
- export default function compose < A , B , C , T1 , R > (
65
- f1 : ( b : C ) => R ,
66
- f2 : ( a : B ) => C ,
67
- f3 : ( a : A ) => B ,
68
- f4 : Func1 < T1 , A >
69
- ) : Func1 < T1 , R >
70
- export default function compose < A , B , C , T1 , T2 , R > (
71
- f1 : ( b : C ) => R ,
72
- f2 : ( a : B ) => C ,
73
- f3 : ( a : A ) => B ,
74
- f4 : Func2 < T1 , T2 , A >
75
- ) : Func2 < T1 , T2 , R >
76
- export default function compose < A , B , C , T1 , T2 , T3 , R > (
77
- f1 : ( b : C ) => R ,
78
- f2 : ( a : B ) => C ,
79
- f3 : ( a : A ) => B ,
80
- f4 : Func3 < T1 , T2 , T3 , A >
81
- ) : Func3 < T1 , T2 , T3 , R >
82
-
83
- /* rest */
84
- export default function compose < R > (
85
- f1 : ( b : any ) => R ,
86
- ...funcs : Function [ ]
87
- ) : ( ...args : any [ ] ) => R
88
-
89
- export default function compose < R > ( ...funcs : Function [ ] ) : ( ...args : any [ ] ) => R
90
-
91
- export default function compose ( ...funcs : Function [ ] ) {
13
+ const compose = < Fns extends F . Function < any [ ] , any > [ ] > (
14
+ ...funcs : Fns
15
+ ) : ( (
16
+ ...args : Parameters < Fns [ T . Tail < Fns > [ 'length' ] ] >
17
+ ) => F . Return < T . Head < Fns > > ) => {
92
18
if ( funcs . length === 0 ) {
93
19
// infer the argument type so it is usable in inference down the line
94
- return < T > ( arg : T ) => arg
20
+ // TODO: should probably throw an error here instead
21
+ return ( < T > ( arg : T ) => arg ) as any
95
22
}
96
23
97
24
if ( funcs . length === 1 ) {
@@ -100,3 +27,5 @@ export default function compose(...funcs: Function[]) {
100
27
101
28
return funcs . reduce ( ( a , b ) => ( ...args : any ) => a ( b ( ...args ) ) )
102
29
}
30
+
31
+ export default compose
0 commit comments