我不相信你能写出这个定义。
如果我们看一下lodash 类型声明文件他们不会试图表达这种关系。
interface LoDashStatic {
flow<TResult extends Function>(...funcs: Function[]): TResult;
}
但仅凭这一点还不足以成为排除这种可能性的理由。作者可能忽略了一些事情,所以让我们继续思考一下。
您可以表示各个功能链之间的关系。您在上面的示例中已经这样做了。您可以为多个参数长度创建相同想法的手动版本,但这是因为您正在设置已知链长度并且可以授予单独类型信息的情况。
如果我们要处理可变长度参数的情况,我们必须将参数视为收藏。因为所有变量都必须具有单一(尽管可能参数化)类型,所以该集合对象也必须具有单一类型。然而,各种函数的类型并不一致。(param:A) => B
与以下类型不同(param:B) => C
并且不能存储在同一个类型良好的容器中(除非联合类型,但这些类型也不会扩展)。
在您想要保留像这样的参数列表上的类型信息的情况下,您通常会在两个参数上定义组合函数并将其应用于多个函数。例如,这就是在 Promise 中保留类型信息的方式。为此,您仍然需要详细说明每个单独的参数。它只是让你最终得到正确的输出类型。也就是说,在大多数情况下这就是您想要的,所以一切都很好。
如果 lodash 是用类型良好的函数式语言编写的,那么该流函数可能就不会存在。我想它会被写成一个管道组合对象。
UPDATE:当我说“管道组合对象”时,我的意思是什么?也许是这样的:
class FunctionComposer<T,V> {
constructor(protected func: (param: T) => V) { }
public compose<X>(newFunc: (param:V) => X) {
return new FunctionComposer((x: T) => newFunc(this.func(x)));
}
public out() {
return this.func;
}
}
let composedFunc = new FunctionComposer((x: number) => x * 2)
.compose(x => x.toString())
.out();
// composedFunc has type (param:number) => string