Skip to content

Commit 3766d01

Browse files
author
jedmao
committed
use ts-toolbelt for 'compose' types
1 parent 28cd255 commit 3766d01

File tree

4 files changed

+18
-82
lines changed

4 files changed

+18
-82
lines changed

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"rollup-plugin-terser": "^5.1.1",
9090
"rollup-plugin-typescript2": "^0.24.0",
9191
"rxjs": "^6.5.2",
92+
"ts-toolbelt": "^3.8.63",
9293
"typescript": "^3.5.3",
9394
"typings-tester": "^0.3.2"
9495
},

src/applyMiddleware.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default function applyMiddleware(
7272
dispatch: (action, ...args) => dispatch(action, ...args)
7373
}
7474
const chain = middlewares.map(middleware => middleware(middlewareAPI))
75-
dispatch = compose<typeof dispatch>(...chain)(store.dispatch)
75+
dispatch = compose(...chain)(store.dispatch as typeof dispatch)
7676

7777
return {
7878
...store,

src/compose.ts

Lines changed: 10 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
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'
52

63
/**
74
* 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
1310
* to left. For example, `compose(f, g, h)` is identical to doing
1411
* `(...args) => f(g(h(...args)))`.
1512
*/
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>>) => {
9218
if (funcs.length === 0) {
9319
// 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
9522
}
9623

9724
if (funcs.length === 1) {
@@ -100,3 +27,5 @@ export default function compose(...funcs: Function[]) {
10027

10128
return funcs.reduce((a, b) => (...args: any) => a(b(...args)))
10229
}
30+
31+
export default compose

0 commit comments

Comments
 (0)