Reputation: 610
I want to have a type for chain of operators like
Chain<T, U> = [ T => A, A => B, B => C, C => U ];
So T should be an input and U should be an output, but in the middle there are can be any transformations.
I wish i can do it like this
type Op<T, U> = (data: T, ...args: unknown[]) => U;
type OpChain<T, U> = [] | [ Op<T, U> ] | [ Op<T, infer R>, ...OpChain<R, U> ];
But of coarse it is not working in typescript. Any ideas?
Upvotes: 1
Views: 346
Reputation: 1337
The only use case for what such a type could be created is further calling such a chain. I suggest you create overloads to describe a finite number of signatures. I think up to 10 would be enough and may cover all your cases:
function callChain<T, U>(input: T, f1: (arg: T) => U): U;
function callChain<T, U, RP1>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => U): U;
function callChain<T, U, RP1, RP2>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => U): U;
function callChain<T, U, RP1, RP2, RP3>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => U): U;
function callChain<T, U, RP1, RP2, RP3, RP4>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => RP4, f5: (arg: RP4) => U): U;
function callChain<T, U, RP1, RP2, RP3, RP4, RP5>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => RP4, f5: (arg: RP4) => RP5, f6: (arg: RP5) => U): U;
function callChain<T, U, RP1, RP2, RP3, RP4, RP5, RP6>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => RP4, f5: (arg: RP4) => RP5, f6: (arg: RP5) => RP6, f7: (arg: RP6) => U): U;
function callChain<T, U, RP1, RP2, RP3, RP4, RP5, RP6, RP7>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => RP4, f5: (arg: RP4) => RP5, f6: (arg: RP5) => RP6, f7: (arg: RP6) => RP7, f8: (arg: RP7) => U): U;
function callChain<T, U, RP1, RP2, RP3, RP4, RP5, RP6, RP7, RP8>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => RP4, f5: (arg: RP4) => RP5, f6: (arg: RP5) => RP6, f7: (arg: RP6) => RP7, f8: (arg: RP7) => RP8, f9: (arg: RP8) => U): U;
function callChain<T, U, RP1, RP2, RP3, RP4, RP5, RP6, RP7, RP8, RP9>(input: T, f1: (arg: T) => RP1, f2: (arg: RP1) => RP2, f3: (arg: RP2) => RP3, f4: (arg: RP3) => RP4, f5: (arg: RP4) => RP5, f6: (arg: RP5) => RP6, f7: (arg: RP6) => RP7, f8: (arg: RP7) => RP8, f9: (arg: RP8) => RP9, f10: (arg: RP9) => U): U;
function callChain(input: any, ...funcs: ((...args: any[]) => any)[]) {
return funcs.reduce((input, current) => current(input), input);
}
Upvotes: 1