typescript - Typescript 中的函数组合无需重载

标签 typescript types pipe function-composition

是否可以为函数组合定义 Typescript 类型(请参阅 flowpipe ) 对于任意数量的参数(要组成的函数)不覆盖但能够提示类型?

如果没有类型推断,就会出现 marvelous answer在我之前的question .

唉,这个解决方案仅在显式定义类型时验证链并报告错误:

const badChain = flow(
  (x: number)=>"string",
  (y: string)=>false,
  (z: number)=>"oops"
); // error, boolean not assignable to number

但是所有的论点都是

flow(
  (x: number)=>"string",
  (y: string)=>false,
  z => {/*z is any, but should be inferred as boolean*/}
);

此推理适用于 lodash 和 ramda 类型,但其定义使用了长时间无法维护的重载,如我之前的问题中所述。

有没有办法避免 overwrites并且不会丢失类型推断?

最佳答案

没有办法消除所有重载。类型 R* 参数相互依赖的方式目前在类型系统中无法表达。

我们可以做出的一项改进是消除在第一个函数上添加额外参数的重载(添加 A* 类型参数的函数)。这可以在 3.0 中使用 tuples in rest parameters 来完成

interface LoDashStatic {

    flow<A extends any[], R1, R2>(f1: (...a: A) => R1, f2: (a: R1) => R2): (...a: A) => R2;

    flow<A extends any[], R1, R2, R3>(f1: (...a: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3): (...a: A) => R3;

    flow<A extends any[], R1, R2, R3, R4>(f1: (...a: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4): (...a: A) => R4;

    flow<A extends any[], R1, R2, R3, R4, R5>(f1: (...a: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5): (...a: A) => R5;

    flow<A extends any[], R1, R2, R3, R4, R5, R6>(f1: (...a: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6): (...a: A) => R6;

    flow<A extends any[], R1, R2, R3, R4, R5, R6, R7>(f1: (...a: A) => R1, f2: (a: R1) => R2, f3: (a: R2) => R3, f4: (a: R3) => R4, f5: (a: R4) => R5, f6: (a: R5) => R6, f7: (a: R6) => R7): (...a: A) => R7;

}

declare const _: LoDashStatic;

let f = _.flow((n: number, s: string) => n + s, o => o.toUpperCase()); // f: (n: number, s: string) => string

关于typescript - Typescript 中的函数组合无需重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54212552/

相关文章:

javascript - Aurelia href.bind 不起作用

go - 如何在 Go 中编写接受 string 和 int64 类型的函数?

Powershell 参数 block 接受 [PSTypeName ("MyType")] 数组

在 Haskell 中解析变量类型的元素

c++ - (C++, Windows) 在没有控制台窗口的情况下生成子进程(使用 CreateProcess)

c - 新终端提示后连接到 stdio 打印输出的管道

javascript - 当使用对象文字初始化对象时,不调用覆盖 toString()

typescript - d.ts 声明模块在导入第三方库时不起作用

javascript - 如何初始化 - 使用 TypeScript 的 AngularJs 应用程序

linux - bash |管道到 bash 函数