新闻详情

新闻详情

首页 / 资讯中心 / 详情

TypeScript 类型挑战 00017:用类型系统实现柯里化(Currying)的完整实战指南

发布时间:2026/9/30 14:11:20来源:尧图网络
TypeScript 类型挑战 00017:用类型系统实现柯里化(Currying)的完整实战指南
示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载本篇技术指南围绕 type-challenges 仓库中编号 00017 的困难hard级挑战「柯里化 1」展开讲解如何用 TypeScript 类型系统为任意参数个数的函数推导出柯里化后的类型签名。读完本文你将掌握变长元组variadic tuple与递归条件类型在函数类型变换中的组合用法能够独立完成本挑战并为理解仓库中更高难度的「柯里化 2」动态参数柯里化挑战打下基础。挑战背景柯里化是什么柯里化Currying 是一种将带有多个参数的函数转换为一系列每个只带一个参数的函数的技术。例如一个普通的加法函数const add (a: number, b: number) a b const three add(1, 2)经过柯里化之后它的调用形态会从add(1, 2)变成逐次传参const curriedAdd Currying(add) const five curriedAdd(2)(3)本挑战编号 00017的难点在于传递给Currying的函数参数个数是不确定的你需要在类型层面写出一个通用的变换使得无论传入几个参数、什么类型都能得到对应的逐层柯里化函数类型。本挑战标注了「困难hard」难度并归入#array元组/数组主题分类文档同时建议在TypeScript 4.0下完成这是因为本解法依赖 TS 4.0 引入的「变长元组类型variadic tuple types」能力[...infer Rest]语法。挑战目标与类型规格原文档给出了本挑战的完整规格需要满足以下三点柯里化后的函数每次仅接受一个参数参数逐个被分配接受完所有参数后返回最终结果柯里化函数每一层的返回值类型必须精确推导不能退化成any。也就是说对于(a: string, b: number, c: boolean) true这样的三参数函数期望的类型是(a: string) (b: number) (c: boolean) true题目模板与测试用例解读模板文件本挑战的起点在 questions/00017-hard-currying-1/template.ts模板只有一个空实现declare function Currying(fn: any): any所有参数和返回值都被any吞掉了任务就是把它替换成能正确推导柯里化类型的签名。测试用例仓库为每个挑战都提供了类型级测试用例见 questions/00017-hard-currying-1/test-cases.ts。它通过Equal工具类型定义于 utils/index.d.ts逐一比对推导结果import type { Equal, Expect } from type-challenges/utils const curried1 Currying((a: string, b: number, c: boolean) true) const curried2 Currying((a: string, b: number, c: boolean, d: boolean, e: boolean, f: string, g: boolean) true) const curried3 Currying(() true) type cases [ ExpectEqual typeof curried1, (a: string) (b: number) (c: boolean) true , ExpectEqual typeof curried2, (a: string) (b: number) (c: boolean) (d: boolean) (e: boolean) (f: string) (g: boolean) true , ExpectEqualtypeof curried3, () true, ]从用例中可以提炼出本挑战必须覆盖的三个边界用例输入期望输出覆盖要点curried13 个参数(string, number, boolean)3 层柯里化链基本多参数场景curried27 个参数7 层柯里化链长参数列表与类型逐层对应curried30 个参数() true() true原样返回空参数边界注意curried3说明了一个重要细节当函数没有参数时柯里化结果就是它本身不能推导成错误的形态。解题思路四步构造柯里化类型第一步约束入参并提取参数与返回值首先把Currying的入参约束为函数类型并用infer拆出参数元组Args与返回值Rdeclare function CurryingT extends (...args: any[]) any(fn: T): CurriedT type CurriedF F extends (...args: infer Args) infer R ? /* 递归展开 Args */ : neverinfer Args得到的不是一个函数签名而是一个元组例如[string, number, boolean]这正是后续递归的原料。第二步处理空参数边界当Args是空元组[]时函数没有参数可分直接返回一个接受零参数并返回R的函数类型type CurriedF F extends (...args: infer Args) infer R ? Args extends [] ? () R : /* 继续递归 */ : never这一步对应测试用例中的curried3。第三步逐个拆出参数并递归生成下一层当Args非空时用变长元组语法拆出头元素A与剩余元组RestArgs extends [infer A, ...infer Rest] ? (arg: A) Curried(...args: Rest) R : never这里的关键是拆出第一个参数A作为当前层函数的入参然后把剩余参数 原返回值重新包成一个函数(...args: Rest) R继续交给Curried递归处理。每次递归吞掉一个参数直到Rest为空触发第二步的边界分支。第四步完整的参考解法将以上三步组合得到一份可提交的解法declare function CurryingT extends (...args: any[]) any(fn: T): CurriedT type CurriedF F extends (...args: infer Args) infer R ? Args extends [] ? () R : Args extends [infer A, ...infer Rest] ? (arg: A) Curried(...args: Rest) R : never : never用测试用例验证推导过程对(a: string, b: number, c: boolean) true第一轮拆出string得到(arg: string) Curried(b: number, c: boolean) true第二轮拆出number第三轮拆出boolean后Rest为空落入() R分支返回true最终展开为(a: string) (b: number) (c: boolean) true与curried1的期望完全一致对curried2的 7 参数函数递归会连续展开 7 层类型推导逐一对应对curried3的空参数函数Args extends []直接命中返回() true。知识点剖析这道题练的是什么变长元组类型Variadic Tuple Types[infer A, ...infer Rest]是 TS 4.0 的核心新语法它允许在元组中间/末尾展开剩余元素。没有它我们只能写[infer A, ...]这类无法捕获剩余部分的模式。这正是原文档建议「在 TypeScript 4.0 下完成」的原因——若使用更早版本...infer Rest无法编译通过。条件类型 infer 的递归Curried是典型的递归条件类型它以F extends (...args: infer Args) infer R为入口在真分支内继续构造新的函数类型并调用自身。递归的终止条件是Args extends []与运行时柯里化的「参数耗尽即返回结果」语义一一对应。与仓库相关挑战的关联仓库文档在本挑战底部列出了三条相关挑战可以作为练习链路14・第一个元素用infer A从元组中提取首元素是本挑战[infer A, ...infer Rest]拆解的前置热身16・排除最后一项对元组做「去尾」操作练习元组的拆解与重组462・柯里化 2地狱级进阶版要求柯里化函数每次可接受至少一个参数、数量不限对应bind这类动态传参场景在理解本挑战「每次一个参数」的递归骨架后可进一步挑战该题。验证与运行方式本仓库是类型挑战集合所有用例通过Equal进行编译期断言。完成template.ts的填写后可在本地运行 TypeScript 编译器仓库根目录 package.json 的 devDependencies 中配置了typescript ^5.3.3以tsc检查 questions/00017-hard-currying-1/test-cases.ts 是否存在类型错误npx tsc --noEmit questions/00017-hard-currying-1/test-cases.ts若Equal断言通过说明你的Curried类型推导与期望完全一致Equal的实现基于函数参数逆变比较比简单的extends互检更严格见 utils/index.d.ts。小结本挑战的核心价值在于训练「把运行时行为映射为递归类型变换」的思维柯里化把f(a, b, c)变成f(a)(b)(c)类型层面就对应把参数元组[A, B, C]递归展开为(arg: A) (arg: B) (arg: C) R。掌握了「infer 拆元组 递归终止分支 变长元组重组」这套组合拳你就拥有了应对绝大多数函数签名变换类挑战包括后续的柯里化 2的核心能力。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐TypeScript 柯里化类型挑战 Currying 100017-hard从零推导函数柯里化的完整类型签名TypeScript 柯里化类型挑战 Currying 100017 hard从零推导函数柯里化的完整类型签名 本篇文章围绕 type challenge示例工程TypeScript 柯里化实战用箭头函数链实现部分应用CurryingTypeScript 柯里化实战用箭头函数链实现部分应用Currying 柯里化Currying是将一个多参数函数拆解为一系列单参数函数的函数式编程技教程type-challenges 题解Hard 难度 Currying 1柯里化 1类型体操完整解析type challenges 题解Hard 难度 Currying 1柯里化 1类型体操完整解析 导读 Currying 1编号 17是 type示例工程上一篇开源项目Anchor CMS快速指南与常见问题解答下一篇Webgrind 开源项目常见问题解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

语音告警防流控方案:QoS优先级队列与DSCP标记实战 2026/9/30 14:59:14

语音告警防流控方案:QoS优先级队列与DSCP标记实战

1. 项目背景与问题定义 1.1 一次真实的“告警失踪”事故 上个月我们处理了一起很有意思的故障。某工厂的安防系统在夜间检测到车间温湿度异常,语音告警平台按预设流程拨打了值班负责人的电话——但负责人并没有接到。不是电话欠费,也不是设备坏了&#…

阅读更多 →
从历史销售订单里捞「客户 × 物料」价格底表:金蝶云星空 WebAPI 实操 2026/9/30 14:59:08

从历史销售订单里捞「客户 × 物料」价格底表:金蝶云星空 WebAPI 实操

一、场景与问题 贸易企业做价格体系梳理,第一步永远是同一件事:把历史成交价捞出来,做一张「客户 物料」的价格底表。 没有这张表,客户分级和等级价就没法定——全靠拍脑袋,业务员一定会为每个客户的档位争论不休。 手…

阅读更多 →
H.264/H.265码流解析必备:指数哥伦布编码原理与实战 2026/9/30 14:59:01

H.264/H.265码流解析必备:指数哥伦布编码原理与实战

做音视频开发的同学,早晚要跟指数哥伦布编码(Exp-Golomb)打交道。调试H.264的SPS、翻看H.265的VPS、解析slice header,几乎每一处都会遇到这种变长编码。它看起来就是一堆0和一个1再加一段数据位,但很多人在这一块卡了…

阅读更多 →
VS Code 安装与配置全指南:从环境准备到 C/C++、Python 实战 2026/9/30 14:59:00

VS Code 安装与配置全指南:从环境准备到 C/C++、Python 实战

1. 装 VS Code 之前,先把这几件事想明白 1.1 标题里那个“VS Code”,到底和 Visual Studio 是什么关系 很多人第一次搜 Visual Studio Code 安装和配置时,都会顺手把 Visual Studio 和 Visual Studio Code 混为一谈。按我这些年带新人、看身…

阅读更多 →
AI需求分析实战:从碎片信息到结构化PRD的文档自动化之路 2026/9/30 14:58:54

AI需求分析实战:从碎片信息到结构化PRD的文档自动化之路

干需求分析这些年,我有个特别直观的感受:这工作一半以上的精力,不是花在“分析”上,而是花在“写文档”上。JBoltAI里的需求分析大师,切入点恰好就在这里——它不替你拍板业务,也不假装能做商业决策&#x…

阅读更多 →
SpringBoot+Vue实战:二手交易系统设计与全栈开发指南 2026/9/30 14:58:54

SpringBoot+Vue实战:二手交易系统设计与全栈开发指南

一个"二手物品交易系统",对于做过Java课程设计或者毕业设计的同学来说,绝对是可以直接封神的经典选题。它业务逻辑清晰、功能扩展性强,而且技术栈组合非常成熟——SpringBoot负责后端接口,Vue负责前端页面,M…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉