froebel
Version:
TypeScript utility library
56 lines (55 loc) • 2.79 kB
TypeScript
import type { MakeProm, λ } from "./types";
/**
* Given a list of functions returns a function that will execute the given
* functions one after another, always passing the result of the previous
* function as an argument to the next function.
*
* If one of the given functions returns a promise, the promise will be resolved
* before being passed to the next function.
*
* @example
* ```
* const join = (...chars: string[]) => chars.join('')
* pipe(join, parseInt)('1', '2', '3') // -> 123
*
* const square = (n: number) => n ** 2
*
* // this is equivalent to: square(square(square(2)))
* pipe(square, square, square)(2) // -> 256
*
* // also works with promises:
* fetchNumber :: async () => Promise<number>
* pipe(fetchNumber, n => n.toString()) // async () => Promise<string>
* ```
*/
declare const pipe: <T extends [λ<any[], any>, ...λ<any[], any>[]]>(...funs: CheckPipe<T, CarryReturn<ReturnTypes<T>, Parameters<T[0]>>, false> extends never ? never : T) => PipedFun<T>;
export default pipe;
/**
* Like `pipe` but takes an argument as its first parameter and invokes the pipe
* with it.
*
* Note: unlike in `pipe`, the first function of the pipe must take exactly one
* argument.
*
* @see {@link pipe}
*
* @example
* ```
* applyPipe(2, double, square, half) // -> 8
* ```
*/
export declare const applyPipe: <T extends [λ<[any], any>, ...λ<any[], any>[]]>(arg: Parameters<T[0]>[0], ...funs: CheckPipe<T, CarryReturn<ReturnTypes<T>, Parameters<T[0]>>, false> extends never ? never : T) => CheckPipe<T, CarryReturn<ReturnTypes<T>, Parameters<T[0]>>, false>;
declare type PipedFun<T extends λ[]> = PipeReturn<T> extends never ? never : ((...args: Parameters<T[0]>) => PipeReturn<T>);
declare type PipeReturn<F extends λ[]> = CheckPipe<F, CarryReturn<ReturnTypes<F>, Parameters<F[0]>>>;
declare type FunDef = [Return: any, Args: any[]];
declare type CheckPipe<F extends λ[], D extends FunDef[], Async extends boolean = false> = F extends [any, any, ...any[]] ? (Resolved<D[0][1]> extends Parameters<F[0]> ? CheckPipe<F extends [any, ...infer F_] ? (F_ extends λ[] ? F_ : never) : never, D extends [any, ...infer D_] ? (D_ extends FunDef[] ? D_ : never) : never, Async extends true ? true : ReturnType<F[0]> extends Promise<unknown> ? true : false> : never) : Resolved<D[0][1]> extends Parameters<F[0]> ? (Async extends true ? MakeProm<ReturnType<F[0]>> : ReturnType<F[0]>) : never;
declare type Resolved<T extends unknown> = {
[K in keyof T]: T[K] extends Promise<infer I> ? I : T[K];
};
declare type ReturnTypes<T extends λ[]> = {
[K in keyof T]: ReturnType<T[K]>;
};
declare type CarryReturn<Returns extends any[], Args extends any[]> = Returns extends [
infer A,
...infer B
] ? [[A, Args], ...CarryReturn<B, [A]>] : [];