Skip to content

Instantly share code, notes, and snippets.

@kelsny
Created November 9, 2021 16:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kelsny/04a3cd3d5a8ee1532f64e82094f434c8 to your computer and use it in GitHub Desktop.
Save kelsny/04a3cd3d5a8ee1532f64e82094f434c8 to your computer and use it in GitHub Desktop.
Extension of my previous gist specialized for RxJS
type UnaryFunction<T, R> = (source: T) => R;
type Identity = <T>(source: T) => T;
type Pipe<T, L = void, R extends UnaryFunction<any, any>[] = []> =
T extends []
? R
: L extends void
? T extends [(_: infer P) => infer V, ...infer Rest]
? Pipe<Rest, V, [...R, UnaryFunction<P, V>]>
: never[]
: T extends [(_: L) => infer V, ...infer Rest]
? Pipe<Rest, V, [...R, UnaryFunction<L, V>]>
: never[]
;
type Compose<A> =
A extends []
? Identity
: A extends [UnaryFunction<infer S, infer V>]
? UnaryFunction<S, V>
: A extends [UnaryFunction<infer S, any>, ...UnaryFunction<any, any>[], UnaryFunction<any, infer V>]
? UnaryFunction<S, V>
: never
;
type Valid<A> = A extends UnaryFunction<any, any>[] ? Pipe<A> extends never[] ? never[] : A : never[];
declare function pipe<A extends UnaryFunction<any, any>[]>(...fns: Valid<A>): Compose<Pipe<A>>;
pipe(
(_: string) => 0,
(_: number) => "",
(_: string) => true,
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment