示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载本文聚焦 type-challenges 仓库中的 Easy 级题目Parametersquestions/03312-easy-parameters。该题要求你在不使用 TypeScript 内置ParametersT的前提下用条件类型与infer关键字手写出等价的MyParametersT用于提取任意函数的参数类型元组。读完本文你将彻底掌握infer在函数类型匹配中的用法、元组tuple类型的构建方式以及内置ParametersT的底层实现原理并能将同样的推断技巧迁移到ReturnType、ConstructorParameters等更多场景。题目速览实现内置 ParametersT题目原文韩文版 README.ko.md与英文版 README.md 一致要求如下내장 제네릭ParametersT를 이를 사용하지 않고 구현하세요.不使用内置泛型ParametersT自行实现它。题目给出的示例const foo (arg1: string, arg2: number): void {} type FunctionParamsType MyParameterstypeof foo // [arg1: string, arg2: number]也就是说MyParameterstypeof foo应当得到一个元组类型[string, number]它恰好对应foo的两个参数的类型。注意 TypeScript 元组可以携带具名标签如[arg1: string, arg2: number]题目注释里展示的正是带标签的形式但等价的普通元组[string, number]同样满足要求。这道题在仓库中被标注为easy难度并带有#infer、#tuple、#built-in三个标签infer是本题的核心解题工具tuple是输出结果的类型形态built-in表示目标是对内置工具类型的复刻。从模板文件出发理解类型约束每个挑战在仓库中都配有模板文件本题的模板是 template.tstype MyParametersT extends (...args: any[]) any any模板已经给出了类型参数T的约束条件T extends (...args: any[]) any。这意味着T必须是一个函数类型该函数可以接收任意个、任意类型的参数...args: any[]返回值类型不限 any。这个约束保证了后续对T做模式匹配时不会遇到非函数类型。模板中的 any是待填空的占位符需要替换为真正的实现。在 JavaScript 运行时层面上typeof foo拿到的是函数本身而在类型层面上typeof foo得到的是它的函数类型(arg1: string, arg2: number) void——这正是我们要做类型提取的对象。核心解法条件类型 inferTypeScript 的条件类型conditional type允许我们以T extends X ? Y : Z的形式对类型做模式匹配。当X中出现infer关键字时TypeScript 会尝试推断出对应位置的类型并在真分支中将其作为新类型变量使用。据此标准解法如下type MyParametersT extends (...args: any[]) any T extends (...args: infer P) any ? P : never逐段拆解T extends (...args: infer P) any把传入的函数类型T与具有任意参数列表的函数这一模式做匹配infer P让 TypeScript 推断出整个参数列表的类型由于模板约束保证了T一定是函数类型匹配必然成功直接走真分支返回PP被推断为参数元组例如对(arg1: string, arg2: number) void会得到[string, number]假分支返回never仅是防御性写法实际因约束的存在不会触发。这正是 TypeScript 内置ParametersT的官方实现type ParametersT extends (...args: any) any T extends (...args: infer P) any ? P : never;由此可见本题的标准答案与 TypeScript 内置工具类型的源码几乎一字不差——infer P推断出的P天然就是一个元组类型不需要任何额外的拼接或转换。这就是该题目同时打上#infer与#tuple两个标签的原因答案本身就是一个 infer 推断出的元组。用仓库测试用例验证Equal 与 Expect仓库为每个题目都提供了在线判题的测试文件。本题的 test-cases.ts 定义了三个函数与三组断言import type { Equal, Expect } from type-challenges/utils function foo(arg1: string, arg2: number): void {} function bar(arg1: boolean, arg2: { a: A }): void {} function baz(): void {} type cases [ ExpectEqualMyParameterstypeof foo, [string, number], ExpectEqualMyParameterstypeof bar, [boolean, { a: A }], ExpectEqualMyParameterstypeof baz, [], ]测试覆盖了三种典型场景被测函数期望结果覆盖要点foo(arg1: string, arg2: number): void[string, number]多参数、基础类型bar(arg1: boolean, arg2: { a: A }): void[boolean, { a: A }]含对象字面量类型的参数baz(): void[]零参数函数应得到空元组其中Equal与Expect来自仓库自带的类型工具 utils/index.d.tsexport type ExpectT extends true T export type EqualX, Y (T() T extends X ? 1 : 2) extends (T() T extends Y ? 1 : 2) ? true : falseExpectT要求T必须是字面量true否则编译报错EqualX, Y通过函数类型协变比较实现了对两个类型完全相等的严格判定比extends的双向可赋值更严格能区分any、never等微妙情形。测试用例说明MyParameterstypeof foo必须精确等于[string, number]而不是any、unknown[]或超集类型零参数函数baz的参数列表推断为空元组[]证明infer P对空参数同样成立。在本地验证时可将 template.ts 中的占位符替换为T extends (...args: infer P) any ? P : never再配合 test-cases.ts 运行 TypeScript 编译检查仓库根目录的 package.json 声明了typescript依赖若全部断言通过则解答正确。边界情况与注意事项零参数函数baz(): void会被推断为[]这符合Parameters的行为——返回空元组而非never带默认值或可选参数(a?: string, b 1) void会推断为[a?: string, b?: number]可选参数对应可选元组元素推断逻辑由 TypeScript 的类型推断规则直接给出带标签元组若使用具名参数推断结果可能保留参数名如[arg1: string, arg2: number]这与题目注释展示的形式一致泛型函数对function idT(x: T): TParameterstypeof id推断为[x: unknown]因为typeof拿到的是泛型函数的具体化类型约束之外的类型模板约束T extends (...args: any[]) any使MyParametersnumber这类调用直接报类型错误保证了解答的安全性。延伸infer 在工具类型中的复用掌握本题后infer的其他应用几乎是同一思路的变体这也解释了为什么本题被归类为 easy。仓库中同属 infer 主题的进阶题目还有00002-medium-return-type用T extends (...args: any[]) infer R ? R : any提取返回值类型00003-medium-omit用keyof T与映射类型实现对象键的剔除00062-medium-type-lookup在联合类型上用T extends { type: infer U }做按字段匹配的查找。它们的共同模式可以概括为先用条件类型约束目标形态再用infer在指定位置提取类型最后在真分支中组织输出。你还可以把infer用在数组元素提取T extends [infer F, ...infer R]、字符串模板匹配T extends \${infer A}-${infer B}等场景这些技巧在仓库 [guides](https://link.gitcode.com/i/047f64a4c7dc4f3a1e583196f478bbbf) 目录的进阶指南中均有涉及。可以说把Parameters 这道题吃透就等于打开了 TypeScript 类型编程的大门。小结第 3312 题 Parameters 的核心收获有三点其一typeof运算符可以把运行时函数值转换为类型层面的函数类型其二条件类型配合infer能够从函数类型中精确提取参数列表且结果天然是元组其三一行实现T extends (...args: infer P) any ? P : never恰好就是内置ParametersT的官方源码体现了复刻内置工具类型这类题目#built-in的典型解题路径。对照仓库中的 template.ts 与 test-cases.ts 完成填空并通过测试你就完成了本次挑战。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐type-challenges 第 14 题实现 Firstlt;Tgt; 泛型提取元组首元素类型type challenges 第 14 题实现 Firstlt;Tgt; 泛型提取元组首元素类型 本篇指南基于 type challenges 仓库中示例工程type-challenges 题目精解不使用内置泛型实现 OmitT, KMediumtype challenges 题目精解不使用内置泛型实现 OmitT, K Medium 导读 本篇文章围绕 type challenges http示例工程TypeScript 类型挑战手写实现内置 ReadonlyT 泛型type-challenges 第 7 题TypeScript 类型挑战手写实现内置 ReadonlyT 泛型type challenges 第 7 题 本篇指南聚焦 type challeng示例工程上一篇d2s-editor暗黑破坏神2存档编辑器的终极开源解决方案下一篇终极解决方案智能管理Visual C运行库彻底告别dll缺失烦恼创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考