如何为Ramda curry处理的柯里化函数高效添加TypeScript类型?
为Ramda柯里化后的函数添加高效TypeScript类型定义
先看我们的场景:
有一个接收4个数字参数并返回数字的函数,以及对应的类型定义:
const f = (a, b, c, d) => { /* 业务逻辑 */ } type F = (a: number, b: number, c: number, d: number) => number;
用Ramda的curry工具柯里化后得到fc:
import { curry } from 'ramda' const fc = curry(f)
现在遇到两个问题:
fc支持多种调用方式(比如全参数调用、逐参数调用、混合参数调用等),不想手动枚举所有重载类型- 一旦导出
fc,TypeScript就会报错:
推断出的'fc'类型必须引用'.pnpm/ts-toolbelt@9.6.0/node_modules/ts-toolbelt/out/Function/Curry'才能命名,这可能不具备可移植性。必须添加类型注解。
解决方案:用通用柯里化类型自动生成类型定义
方案一:利用ts-toolbelt的Curry类型
Ramda的类型定义底层依赖了ts-toolbelt的Curry类型,我们可以直接引入它来生成柯里化后的类型:
import { curry } from 'ramda'; import { Curry } from 'ts-toolbelt'; type F = (a: number, b: number, c: number, d: number) => number; const f: F = (a, b, c, d) => a + b + c + d; // 生成支持所有调用方式的柯里化类型 type CurriedF = Curry<F>; const fc: CurriedF = curry(f); export default fc;
方案二:自己实现通用柯里化类型
如果不想额外依赖ts-toolbelt,可以手动实现一个递归的通用柯里化类型工具,自动覆盖所有参数组合的调用场景:
import { curry } from 'ramda'; // 通用柯里化类型:递归拆分参数,生成支持部分调用的联合类型 type Curry<T extends (...args: any[]) => any> = T extends (...args: infer Args) => infer R ? Args extends [infer First, ...infer Rest] ? // 同时支持传第一个参数返回柯里化函数,或传全参数直接返回结果 ((arg: First) => Curry<(...args: Rest) => R>) & T : R : never; type F = (a: number, b: number, c: number, d: number) => number; const f: F = (a, b, c, d) => a + b + c + d; // 给fc指定自动生成的柯里化类型 const fc: Curry<F> = curry(f); export default fc;
报错原因说明
导出时的类型错误,是因为TypeScript自动推断的fc类型依赖了ts-toolbelt内部未导出的Curry类型,外部无法访问这个隐式依赖的类型。手动给fc指定我们自己定义/引入的可访问类型后,这个问题就会解决。
内容的提问来源于stack exchange,提问作者Undistraction
相关产品推荐
相关产品推荐

