TypeScript 中管道和组合函数的类型推断不精确

问题描述 投票:0回答:1

我定义了

pipe
compose
函数,每个函数都能够将两个函数组合成一个新函数,唯一的区别是应用于参数时的调用顺序。

这两个函数都是通用的,我希望我可以使乘积函数成为强类型,但有些东西是关闭的,并且结果函数类型被错误地推断出来。

问题:

  1. 是语言的限制还是我做错了什么?
  2. 如果可以在 TypeScript 中修复它,我该如何修复它?
function pipe<X, Y, Z>(first: (x: X) => Y): (f2: (y: Y) => Z) => (x: X) => Z {
  return function (second: (y: Y) => Z): (x: X) => Z {
    return function (x: X): Z {
      return second(first(x));
    };
  }
}

function compose2<X, Y, Z>(second: (y: Y) => Z): (f2: (x: X) => Y) => (x: X) => Z {
  return function (first: (x: X) => Y): (x: X) => Z {
    return function (x: X): Z {
      return second(first(x));
    };
  }
}

使用方法

function numToStr(n: number): string { return n.toString(); }
function strToLen(s: string): number { return s.length; }

// Inferred as (x: number) => unknown
// Should be (x: number) => number
const f1 = pipe(numToStr)(strToLen);

// Inferred as(x: unknown) => number
// Should be (x: number) => number
const f2 = compose(strToLen)(numToStr);
typescript functional-programming typescript-generics
1个回答
0
投票

而不是硬编码每个函数的返回类型。允许打字稿推断它并确保不太早使用通用参数:

function pipe<X, Y>(first: (x: X) => Y) {
  return function <Z>(second: (y: Y) => Z) {
    return function (x: X) {
      return second(first(x));
    };
  }
}

function compose<Y, Z>(second: (y: Y) => Z) {
  return function <X>(first: (x: X) => Y) {
    return function (x: X): Z {
      return second(first(x));
    };
  }
}

function numToStr(n: number): string { return n.toString(); }
function strToLen(s: string): number { return s.length; }

const f1 = pipe(numToStr)(strToLen);
const f2 = compose(strToLen)(numToStr);
© www.soinside.com 2019 - 2024. All rights reserved.