是否可以为函数组合定义 Typescript 类型(请参阅 flow 或 pipe ) 对于任意数量的参数(要组成的函数)不覆盖但能够提示类型?
如果没有类型推断,就会出现 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/