是否可以键入“ spreadCall”方法?有条件类型和推理的难题

时间:2019-01-08 23:49:30

标签: typescript conditional-types

我在工作时遇到一个问题,可以用此示例进行总结:是否可以完全键入以下函数?


    function spreadCall(f1, f2) {
        const args = f1();
        f2(...args);
    }

因此,我们需要f2接受完全相同数量的参数(即元组),类型相同的顺序作为f1的结果。我想不通这样做的方法-我能想到的部分解决方案是枚举多个参数,即


    type Output<F> = 
         F extends ()=>[infer A0] ? (a0:A0)=>void :
         F extends ()=>[infer A0, infer A1] ? (a0:A0, a1:A1)=>void :
         F extends ()=>[infer A0, infer A1, infer A2] ? (a0:A0, a1:A1, a2:A2)=>void :
         never;
    // enumerate as many number of arguments as desired ^^

    function spreadCall<InputF>(f1:InputF, f2:Output<InputF>) {
        // ...
    }

有没有一种方法可以处理任意数量的参数?

1 个答案:

答案 0 :(得分:2)

我认为您可以使用generic rest parameter type做您想做的事情:

function spreadCall<A extends any[]>(f1: () => A, f2: (...args: A) => any) {
    const args = f1();
    f2(...args);
}

f1的返回值必须是与f2函数的参数类型匹配的tuple

declare function input(): [number, string]
declare function output(a: number, b: string): void;

spreadCall(input, output);