Skip to content

Instantly share code, notes, and snippets.

@snoble
Created May 31, 2023 22:00
Show Gist options
  • Save snoble/c7423b43e35f4ba5ddec0100357e1f04 to your computer and use it in GitHub Desktop.
Save snoble/c7423b43e35f4ba5ddec0100357e1f04 to your computer and use it in GitHub Desktop.
type Func<A = any, B = any> = (arg: A) => B;
type OkFuncList<L> = L extends [
Func<infer A1, infer B1>,
Func<infer A2, infer B2>,
...infer Rest
]
? B1 extends A2
? [Func<A1, B1>, ...OkFuncList<[Func<A2, B2>, ...Rest]>]
: never
: L extends [Func<any, any>]
? L
: never;
type FirstType<L> = L extends [Func<infer A1, any>, ...infer _] ? A1 : never;
type LastType<L> = L extends [...infer _, Func<any, infer B1>] ? B1 : never;
const composeFunctions = <L>(
fns: OkFuncList<L>
): ((arg: FirstType<L>) => LastType<L>) => {
return (arg) => fns.reduce<any>((x, fn) => fn(x), arg);
};
const fn: (arg: string) => number[] = composeFunctions([
(arg: string) => arg.length,
(arg: number) => [arg],
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment