如何在打字稿中制作一种函数链(数组)?
How to make a type of chain (array) of functions in typescript?
我想要像
这样的运算符链类型
链 = [ T => A, A => B, B => C, C => U];
所以T应该是输入,U应该是输出,但中间可以有任何转换。
我希望我能这样做
type Op<T, U> = (data: T, ...args: unknown[]) => U;
type OpChain<T, U> = [] | [ Op<T, U> ] | [ Op<T, infer R>, ...OpChain<R, U> ];
但粗略地说,它不适用于打字稿。有什么想法吗?
可以创建此类类型的唯一用例是进一步调用此类链。我建议您创建重载来描述有限数量的签名。我认为最多 10 个就足够了,可以涵盖您的所有情况:
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);
}
我想要像
这样的运算符链类型链
所以T应该是输入,U应该是输出,但中间可以有任何转换。
我希望我能这样做
type Op<T, U> = (data: T, ...args: unknown[]) => U;
type OpChain<T, U> = [] | [ Op<T, U> ] | [ Op<T, infer R>, ...OpChain<R, U> ];
但粗略地说,它不适用于打字稿。有什么想法吗?
可以创建此类类型的唯一用例是进一步调用此类链。我建议您创建重载来描述有限数量的签名。我认为最多 10 个就足够了,可以涵盖您的所有情况:
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);
}