Created
October 14, 2019 05:39
-
-
Save aaronyo/1d4a915a4fea841a47a7416040ee9bd4 to your computer and use it in GitHub Desktop.
Pipe, compose and the trouble with typescript generics... conclusion: pipe is better than compose in typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fp from 'lodash/fp'; | |
function compose<TS extends any[], R>( | |
f1: (...args: TS) => R, | |
): (...args: TS) => R; | |
function compose<TS extends any[], R1, R2>( | |
f1: (a: R1) => R2, | |
f2: (...args: TS) => R1, | |
): (...args: TS) => R2; | |
function compose(...args: any) { | |
return fp.compose(...args); | |
} | |
function asyncPipe<TS extends any[], R>( | |
f1: (...args: TS) => Promise<R> | R, | |
): (...args: TS) => Promise<R>; | |
function asyncPipe<TS extends any[], R1, R2>( | |
f1: (...args: TS) => Promise<R1> | R1, | |
f2: (a: R1) => Promise<R2> | R2, | |
): (...args: TS) => Promise<R2>; | |
function asyncPipe(...fns: any[]) { | |
return async (...args: any[]) => | |
fp.reduce( | |
(sum: any, fn: (value: any) => any) => Promise.resolve(sum).then(fn), | |
fp.head(fns)(...args), | |
fp.tail(fns), | |
); | |
} | |
function asyncCompose<TS extends any[], R>( | |
f1: (...args: TS) => Promise<R> | R, | |
): (...args: TS) => Promise<R>; | |
function asyncCompose<TS extends any[], R1, R2>( | |
f2: (a: R1) => Promise<R2> | R2, | |
f1: (...args: TS) => Promise<R1> | R1, | |
): (...args: TS) => Promise<R2>; | |
function asyncCompose(...fns: any[]) { | |
fns = fp.reverse(fns); | |
return async (...args: any[]) => | |
fp.reduce( | |
(sum: any, fn: (value: any) => any) => Promise.resolve(sum).then(fn), | |
fp.head(fns)(...args), | |
fp.tail(fns), | |
); | |
} | |
// const compose: ComposeFn = f1 => { | |
// return a => f1(a); | |
// }; | |
//const compose: ComposeFn = fp.compose; | |
//const result = fp.compose(fp.map(fp.isNumber))([1, 2, 3]); | |
const result = compose( | |
fp.map(fp.isNumber), | |
fp.map, | |
)((a: number) => a * 2, [1, 2, 3]); | |
const asyncResult = asyncPipe(fp.map((a: number) => a * 2), a => a)([1, 2, 3]); | |
const asyncResult2 = asyncCompose(a => a, fp.map((a: number) => a * 2))([ | |
1, | |
2, | |
3, | |
]); | |
//const result = compose(fp.isNumber)(1); | |
//const result = fp.map(fp.isNumber)([1, 2, 3]); | |
const add = (a: number, b: number) => a + b; | |
let rr = fp.reduce(add, 0, [1, 2, 3]); | |
// fails | |
result[1] = true; | |
const main = async () => { | |
// pipe works | |
const r = await asyncResult; | |
r[1] = 1; | |
//compose fails -- type of r2 unknown | |
const r2 = await asyncResult2; | |
r2[1] = 1; | |
}; | |
main(); | |
//rr = 'hello'; | |
console.log(rr); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment