/* eslint-disable no-unused-vars */ type AnyFunc = (...arg: any) => any; type LastFnReturnType, Else = never> = F extends [ ...any[], (...arg: any) => infer R ] ? R : Else; type PipeArgs = F extends [ (...args: infer A) => infer B ] ? [...Acc, (...args: A) => B] : F extends [(...args: infer A) => any, ...infer Tail] ? Tail extends [(arg: infer B) => any, ...any[]] ? PipeArgs B]> : Acc : Acc; export const pipe = ( arg: Parameters[0], firstFn: FirstFn, ...fns: PipeArgs extends F ? F : PipeArgs ): LastFnReturnType> => (fns as AnyFunc[]).reduce((acc, fn) => fn(acc), firstFn(arg));