Skip to content

Instantly share code, notes, and snippets.

@MKRhere
Created July 16, 2024 11:07
Show Gist options
  • Save MKRhere/44edf371d7086eef17b6f9eb5010103b to your computer and use it in GitHub Desktop.
Save MKRhere/44edf371d7086eef17b6f9eb5010103b to your computer and use it in GitHub Desktop.
TypeScript implementation of Compose
const sum = (a: number, b: number) => a + b;
const precision = (a: number) => a.toFixed(2);
const printer = (a: string) => (console.log(a), a);
// O = Binary Compose
type O<G extends (arg: ReturnType<F>) => any, F extends (...args: any[]) => any> =
//
(...args: Parameters<F>) => ReturnType<G>;
type ParseCompose<Fs extends ((...args: any[]) => any)[]> = Fs extends [...infer Head, infer G, infer F]
? F extends (...args: any[]) => infer A
? G extends (arg: A) => any
? Head extends []
? O<G, F>
: Head extends ((...args: any[]) => any)[]
? ParseCompose<[...Head, O<G, F>]>
: never
: never
: never
: never;
type Compose = <Fs extends ((...args: any[]) => any)[]>(...fs: Fs) => ParseCompose<Fs>;
type x = ParseCompose<[typeof printer, typeof precision, typeof sum]>;
const compose = ((...fs: ((...args: any[]) => any)[]) =>
fs.reduceRight(
(f, g) =>
(...args) =>
f(g(...args)),
)) as Compose;
const composed = compose(printer, precision, sum);
composed(1, 2); // $ExpectType string
const composed2 = compose(printer, sum);
composed2(1, 2); // $ExpectError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment