通用 curry 函数的 typescript 类型

标签 typescript generics currying

我正在尝试使用 FP 变得更好,但正在努力如何处理输入通用的“curry”函数。
例如,我写了一个“ 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 函数.
当你在没有 curry 调用的情况下看到它时更明显:
const sumNumbersFn = reduce((sum, n) => sum + n, 0);
在这种情况下,您可以通过使用 n: number 键入函数本身的参数来解决此问题。或显式设置通用参数 <number[], number> .
前者似乎是合理的,但我遇到的是,随着事情变得越来越复杂,我必须不断提供通用签名。
我想知道我是否遗漏了什么,实际上有可能让 typescript 从后面的函数调用中“推断”出类型吗?
回到第一个例子:
const result = reduce((sum, n) => sum + n, 0)(numToSum);
似乎编译器实际上应该拥有推断类型所需的所有信息。
也许我的类型刚刚关闭?
更新
这是我遇到的问题的更具体/完整示例
TS-Playground

最佳答案

您所要做的就是声明一个从 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 配置设置。因此,我将解决方案编写为函数声明而不是函数表达式。

关于通用 curry 函数的 typescript 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64836780/

相关文章:

node.js - 找不到 EmailInstructorsComponent 的组件工厂。你把它添加到@NgModule.entryComponents 了吗?

Java 泛型,将所有整数/vector 添加到列表中

java 泛型 T 扩展 Simpletype?

javascript - thunk 和函数柯里化(Currying)相同吗?

f# - 如何在 F# 类型提供程序中构建任意柯里化(Currying)函数?

javascript - Discord JS - DiscordAPIError : Missing Access

typescript - 如何在使用 Compiler API 进行类型检查之前转换 TypeScript 代码

TypeScript:如何从项目中删除 *.js.map 文件

java - 构造中的泛型 : Java does not recognize that my own class implements an interface

Bind 与 curry* 的 JavaScript 用法?