Challenge
在本次挑战中,您需要为 Currying 函数声明相应的类型,以帮助 TypeScript 编译器推断出正确的类型。
在上面的代码中,我们使用了两个工具类型 Expect 和 Equal,它们的实现代码如下:
Solution
首先,我们来分析一下第一个测试用例:
图片
由上图可知,我们需要获取参数列表的类型和函数的返回值类型。参数列表类型要包含参数的名称和参数的类型。那么如何获取函数类型的参数列表类型和返回值类型呢?这时我们可以使用 TypeScript 内置的 Parameters 和 ReturnType 工具类型。
图片
在以上代码中,Parameters 工具类型用于获取函数类型的参数列表类型,它返回的是元组类型。而 ReturnType 工具类型则用于获取函数类型的返回值类型。它们的实现代码如下所示:
在以上代码中,使用了 TypeScript 条件类型和 infer 类型推断。了解完以上代码,我们就知道如何获取函数类型的参数列表类型和返回值类型了。
接下来,我们要实现的功能就是使用函数的参数类型和返回值类型生成新的函数类型。下面我们来定义一个新的 ToCurrying 工具类型,它包含两个类型变量 Args 和 Return,分别表示参数的类型和返回值类型:
然后,我们来继续分析第一个测试用例:
图片
参考以上的图片,我们可以总结出 ToCurrying 工具类型的处理流程:
图片
根据上述的处理流程,我们可以利用 TypeScript 条件类型、infer 类型推断和递归类型来实现对应的功能:
有了 ToCurrying 工具类型之后,我们来更新前面声明的 Currying 函数:
更新后的 Currying 函数,已经可以满足前两个测试用例。但还不能满足最后一个测试用例:
图片
这是因为获取 () => true 函数类型的参数列表类型时,返回的是空元组类型,针对这种情形,我们需要进行对应的处理:
在以上代码中,当发现 Args 类型变量对应的类型是空元组类型的话,我们直接返回 () => Return 函数类型。之后,我们就通过了所有的测试用例。最后,我们来看一下完整的代码: