Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@aaronyo
Created October 14, 2019 05:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronyo/1d4a915a4fea841a47a7416040ee9bd4 to your computer and use it in GitHub Desktop.
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
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