Skip to content

Instantly share code, notes, and snippets.

@kelsny
Last active November 9, 2021 16:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kelsny/c4a3ec041a09257b1fa10df7c748aafe to your computer and use it in GitHub Desktop.
Save kelsny/c4a3ec041a09257b1fa10df7c748aafe to your computer and use it in GitHub Desktop.
Arbitrary arity pipe function typings
type UnaryFunction<T, R> = (source: T) => R;
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 [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,
);
@kelsny
Copy link
Author

kelsny commented Nov 9, 2021

note: haven't gotten to validation of arguments yet

now added :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment