【问题标题】:Typescript Typings for generic curry functions通用咖喱函数的打字稿类型
【发布时间】:2020-11-14 17:42:07
【问题描述】:

我正在努力使 FP 变得更好,但在处理键入通用“咖喱”函数时遇到了困难。

例如,我写了一个“Curry”版本的 reduce:

const reduce = <S, R>(fn: (result: R, obj: S, i?: number, arr?: S[]) => R, init: R) => 
(objects: S[]) => 
objects.reduce(fn, init);

const numToSum: number[] = [1,2,3,5,8,13];

const result = reduce((sum, n) => sum + n, 0)(numToSum);

问题是 typescript 显然无法知道 S 的类型,直到您实际使用 numToSum 调用 curry 函数。

当你看到它没有咖喱调用时会更明显:

const sumNumbersFn = reduce((sum, n) => sum + n, 0);

在这种情况下,您可以通过使用 n: number 键入函数本身的参数或显式设置泛型参数 &lt;number[], number&gt; 来解决此问题。

前者似乎是合理的,但我遇到的是随着事情变得越来越复杂,我不得不不断地提供通用签名。

我想知道我是否遗漏了什么,实际上有可能让 typescript 从后面的函数调用中“推断”出类型?

回到第一个例子:

const result = reduce((sum, n) => sum + n, 0)(numToSum);

似乎编译器实际上应该拥有推断类型所需的所有信息。

也许我的类型刚刚结束?

更新

这是我遇到的问题的更具体/完整的示例

TS-Playground

【问题讨论】:

  • 我知道stackoverflow.com/questions/60203078/… 非常相似(在标题中)......我认为问题的核心是不同的,但如果你认为这是重复的,我的感受不会受到伤害
  • 我也不确定我所做的是否是正确的 fp。如果我上面写的是一个不正确的应用程序,我不会感到惊讶
  • 我认为 TS 永远无法从您最终传递给返回函数的值中推断出泛型类型 - 例如,您可以分配 reduce 的返回值并使用多个不同的值调用它。
  • @jonrsharpe 如果你有时间,请查看我刚刚添加的 ts-playground 链接......它可能更好地描述了我试图克服的问题

标签: typescript generics currying


【解决方案1】:

您所要做的就是将您从select 函数返回的函数声明为泛型:

function select<T, S>(sFn: (obj: T) => S) {
  function computation<G>(fn: (obj: S) => G) {
    return (obj: T) => fn(sFn(obj));
  }

  return computation;
} 

P.S:我不知道为什么这种语法在 TS 操场上不起作用:

const select = <T, S>(sFn: (obj: T) => S) => <G>(fn: (obj: S) => G) => {
  return (obj: T) => fn(sFn(obj));
}

可能是因为某些 TS 配置设置。因此,我将解决方案编写为函数声明而不是函数表达式。

【讨论】:

  • 啊,伙计……我摔得太狠了,而且离得太近了。我实际上沿途尝试了“函数表达式”版本(可能多次)。你的英雄!
猜你喜欢
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 2017-01-18
  • 2019-04-14
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多