Skip to content

Instantly share code, notes, and snippets.

@jordangarcia
Created April 12, 2025 01:41
Show Gist options
  • Save jordangarcia/ba32cc5d691e9a39d5763369d83b6dff to your computer and use it in GitHub Desktop.
Save jordangarcia/ba32cc5d691e9a39d5763369d83b6dff to your computer and use it in GitHub Desktop.
// Type for a value that might be a Promise
type MaybePromise<T> = T | Promise<T>;
// Async pipe with proper type inference for up to 10 functions
function asyncPipe<A, B>(
ab: (a: A) => MaybePromise<B>
): (a: A) => Promise<B>;
function asyncPipe<A, B, C>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>
): (a: A) => Promise<C>;
function asyncPipe<A, B, C, D>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>
): (a: A) => Promise<D>;
function asyncPipe<A, B, C, D, E>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>
): (a: A) => Promise<E>;
function asyncPipe<A, B, C, D, E, F>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>,
ef: (e: E) => MaybePromise<F>
): (a: A) => Promise<F>;
function asyncPipe<A, B, C, D, E, F, G>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>,
ef: (e: E) => MaybePromise<F>,
fg: (f: F) => MaybePromise<G>
): (a: A) => Promise<G>;
function asyncPipe<A, B, C, D, E, F, G, H>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>,
ef: (e: E) => MaybePromise<F>,
fg: (f: F) => MaybePromise<G>,
gh: (g: G) => MaybePromise<H>
): (a: A) => Promise<H>;
function asyncPipe<A, B, C, D, E, F, G, H, I>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>,
ef: (e: E) => MaybePromise<F>,
fg: (f: F) => MaybePromise<G>,
gh: (g: G) => MaybePromise<H>,
hi: (h: H) => MaybePromise<I>
): (a: A) => Promise<I>;
function asyncPipe<A, B, C, D, E, F, G, H, I, J>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>,
ef: (e: E) => MaybePromise<F>,
fg: (f: F) => MaybePromise<G>,
gh: (g: G) => MaybePromise<H>,
hi: (h: H) => MaybePromise<I>,
ij: (i: I) => MaybePromise<J>
): (a: A) => Promise<J>;
function asyncPipe<A, B, C, D, E, F, G, H, I, J, K>(
ab: (a: A) => MaybePromise<B>,
bc: (b: B) => MaybePromise<C>,
cd: (c: C) => MaybePromise<D>,
de: (d: D) => MaybePromise<E>,
ef: (e: E) => MaybePromise<F>,
fg: (f: F) => MaybePromise<G>,
gh: (g: G) => MaybePromise<H>,
hi: (h: H) => MaybePromise<I>,
ij: (i: I) => MaybePromise<J>,
jk: (j: J) => MaybePromise<K>
): (a: A) => Promise<K>;
// Implementation that works for any number of functions
function asyncPipe(...fns: Array<(arg: any) => MaybePromise<any>>): (arg: any) => Promise<any> {
return async (x: any) => {
return fns.reduce(async (acc, fn) => fn(await acc), x);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment