type-challenges 第 191 题详解:Append Argument 为函数类型追加参数
示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载导读Append Argument是 type-challenges 题库中编号 191 的中等难度medium题目标签为arguments。它要求你实现一个泛型工具AppendArgumentFn, A给定任意函数类型Fn与任意类型A生成一个与Fn签名一致、但末尾额外追加一个类型为A的参数的新函数类型G。这道题是练习条件类型Conditional Types与infer模式匹配的经典入口读完后你将掌握如何解构函数参数列表、如何借助内建Parameters工具类型重组函数签名以及如何利用仓库自带的测试框架验证类型级实现的正确性。题目背景与要求题目由 Maciej Sikora 创作从其在 Dev.to 上发表的进阶 TypeScript 练习文章移植而来并被收录进本仓库的 medium 级别挑战列表见 README.md 中191・Append Argument条目。仓库元数据 info.yml 明确记录难度为medium标签为arguments。原题描述见 README.ja.md对于给定的函数类型Fn与任意类型A这里的任意指不做类型限制实现一个泛型类型AppendArgumentFn, A它接受Fn作为第一个类型参数、A作为第二个类型参数产出一个新函数类型G——G拥有Fn的全部参数并在最后追加一个类型为A的参数。官方给出的示例type Fn (a: number, b: string) number type Result AppendArgumentFn, boolean // 期望得到 (a: number, b: string, x: boolean) number可以看到追加的参数名在类型层面并无实际约束x只是示意真正重要的是参数的类型number、string保持不变末尾新增boolean返回值number也原样保留。从模板到答案解题路径分析仓库为每道题都提供了起始模板 template.ts本题模板只有一行type AppendArgumentFn, A any任务就是用具体实现替换any。要完成它需要先弄清两个关键点如何取出Fn的参数列表TypeScript 内建工具类型ParametersF可以直接提取函数类型的参数元组例如Parameters(a: number, b: string) number得到[number, string]。如何取出返回值类型内建工具类型ReturnTypeF提取函数返回值例如ReturnType(a: number, b: string) number得到number。在此基础上追加参数的本质就是拼接元组把A接到原参数元组的末尾形成新的参数列表再用它与原返回值组合出新的函数类型。解法一借助内建工具类型最直白的实现是利用Parameters、ReturnType与元组展开type AppendArgumentFn extends (...args: any[]) any, A Fn extends (...args: infer P) infer R ? (...args: [...P, A]) R : never这里用条件类型配合infer P捕获Fn的参数元组、infer R捕获返回值然后构造新签名(...args: [...P, A]) R。[...P, A]是变长元组展开语法将A拼接到元组末尾。更简洁的等价写法是直接使用内建工具类型type AppendArgumentFn extends (...args: any[]) any, A (...args: [...ParametersFn, A]) ReturnTypeFnParametersFn取得原参数元组ReturnTypeFn取得原返回值二者通过新函数签名重组。这种写法可读性更高且语义与复用原签名、追加尾部参数完全一致。解法二纯infer模式匹配若想避开内建工具类型也可以完全依靠infer手工拆解type AppendArgumentFn, A Fn extends (...args: infer Args) infer Return ? (...args: [...Args, A]) Return : never两种解法的核心思想一致条件类型 infer 提取 元组展开重组。这也是题库中大量arguments标签题目如 3196・Flip Arguments、3312・Parameters共通的底层套路相关概念可进一步参考本仓库 guides/infer.md 的专题说明。测试用例与判定逻辑解读仓库为每道题配有 test-cases.ts这是验证实现正确性的权威依据。本题共有三个用例import type { Equal, Expect } from type-challenges/utils type Case1 AppendArgument(a: number, b: string) number, boolean type Result1 (a: number, b: string, x: boolean) number type Case2 AppendArgument() void, undefined type Result2 (x: undefined) void type cases [ ExpectEqualCase1, Result1, ExpectEqualCase2, Result2, // ts-expect-error AppendArgumentunknown, undefined, ]逐个解读Case1正例AppendArgument(a: number, b: string) number, boolean必须严格等于(a: number, b: string, x: boolean) number。这里使用Equal做深度类型相等判断Equal的实现位于 utils/index.d.ts通过构造(T() T extends X ? 1 : 2)与(T() T extends Y ? 1 : 2)的可赋值性比较来判定 X、Y 是否完全相等比单纯的extends双向判断更严格。Case2正例零参数函数AppendArgument() void, undefined必须得到(x: undefined) void。这验证了实现必须能处理没有参数的函数——Parameters() void是空元组[]展开后追加undefined得到[undefined]恰好构造出带一个undefined参数的函数。Case3负例// ts-expect-error标注在AppendArgumentunknown, undefined上表示这一行必须产生类型错误。因为unknown不是函数类型如果我们的实现给Fn加了extends (...args: any[]) any约束两种解法都加了那么传入unknown会触发泛型约束检查错误正好满足该负例的期望。反之如果实现不加约束unknown extends (...args: infer Args) infer Return不成立会走never分支——AppendArgumentunknown, undefined的结果是never同样会使ts-expect-error生效。无论哪条路径负例都要求实现对非函数类型不产出合法函数签名。ExpectT extends true的定义见 utils/index.d.ts它要求传入的类型必须是字面量true从而把类型层面的断言转化为编译期硬校验只要实现不满足任一用例tsc就会直接报错。边界情况与进阶讨论rest 参数与可选参数由于ParametersFn保留原始参数列表的结构化信息追加操作对以下形态的签名同样成立type F (...args: [number, string]) boolean // AppendArgumentF, Date 得到 (...args: [number, string, Date]) boolean不过需要留意对于带可选参数的函数如(a?: number) voidParameters提取的结果是[a?: number]追加后新参数的必选性与位置语义取决于展开结果这一细节是生产环境中使用本工具时容易踩坑的地方。与相似题目的对比本仓库中还有一个容易混淆的题目 527・Append to object见 questions/00527-medium-append-to-object它是在对象类型上追加键而本题是在函数参数列表上追加参数。两者的共同点都是保持原结构不变、在尾部扩展但操作对象一个是对象的属性集合一个是函数的参数元组对应了类型系统里对象映射与函数签名重组两条不同技术线。约束与返回类型的选择给Fn加extends (...args: any[]) any约束是推荐做法它一方面让Parameters/infer的用法安全保证输入确实是可调用的函数类型另一方面让负例用例传入unknown自然报错符合 test-cases.ts 第三行的预期。never作为条件类型的失败分支则保证了在极端输入下类型不会悄悄退化成any。在本地验证你的实现本仓库支持在本地 IDE 中直接运行全部挑战。按 README.md 的说明环境要求安装最新版 Node.js 与 pnpm然后# 克隆仓库并安装依赖 pnpm install # 生成 playground 工程会提示选择语言 pnpm generate生成后的工程位于./playground目录其中每道题都包含template.ts待填空的实现与test-cases.ts判题用例。将实现写入AppendArgument后运行 TypeScript 类型检查IDE 内或tsc --noEmit即可看到用例是否全部通过。若之后想更新 playground 但保留自己的解答可执行pnpm generate --keep-changes # 或简写 pnpm generate -K对本题而言只要你的AppendArgument能同时让 test-cases.ts 中的两个ExpectEqual...断言通过、并让ts-expect-error行保持报错就说明实现与官方判定完全一致。小结Append Argument是一个看似简单、实则覆盖了条件类型、infer提取、元组展开与泛型约束四大核心机制的 medium 题目。它的标准解法(...args: [...ParametersFn, A]) ReturnTypeFn在函数类型变换类需求装饰器、中间件签名扩展、事件处理器参数注入等场景中有广泛参考价值。结合本仓库提供的 template.ts、test-cases.ts 与 utils/index.d.ts 中的断言工具你可以在本地完整复现并验证这一类型级变换的每一个细节。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐BabelDOC 新手指南10 分钟把英文 PDF 翻成中英双语对照BabelDOC 新手指南10 分钟把英文 PDF 翻成中英双语对照 BabelDOC 是一款开源的 PDF 文档翻译工具它的核心功能是 PDF 双语对照翻人工智能AI 应用NLP计算机视觉type-challenges 第 2 题解析用 infer 手写 ReturnTypeT获取函数返回类型type challenges 第 2 题解析用 infer 手写 ReturnTypeT 获取函数返回类型 本文围绕 type challenges 题示例工程x64dbg AddArg 命令详解为函数类型逐个追加参数的完整指南x64dbg AddArg 命令详解为函数类型逐个追加参数的完整指南 AddArg 是 x64dbg 类型系统命令族中的一员用于向已存在的函数类型末尾追加一逆向工程调试器开发工具应用安全上一篇OpCore-Simplify重构黑苹果配置流程的自动化工具下一篇自动化配置革命OpCore Simplify如何解决黑苹果EFI构建技术痛点创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →