ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TypeScript 类型挑战 00002:手写 `ReturnType<T>`,用 infer 提取函数返回类型

TypeScript 类型挑战 00002:手写 `ReturnType<T>`,用 infer 提取函数返回类型 示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载本篇文章围绕 type-challenges 仓库中编号 00002 的中等难度题目「Get Return Type」展开。题目要求在不使用内置ReturnTypeT的前提下自行实现一个等价的MyReturnTypeT泛型用于从函数类型中提取其返回值类型。读完本文你将掌握条件类型与infer关键字的组合用法、函数类型参数位置上的类型推断模式以及如何借助仓库中的测试用例验证自己实现的正确性。题目解读挑战书原文这道题位于 questions/00002-medium-return-type/README.ko.md由 Anthony Fuantfu发起难度等级为 medium보통标签为#infer与#built-in见 info.yml。题目原文要求非常简洁내장 제네릭ReturnTypeT을 이를 사용하지 않고 구현하세요.不使用内置泛型ReturnTypeT实现它。配套示例const fn (v: boolean) { if (v) return 1 else return 2 } type a MyReturnTypetypeof fn // should be 1 | 2fn的返回类型被 TypeScript 推断为1 | 2数字字面量联合类型因此MyReturnTypetypeof fn应推导出1 | 2。注意题目名称「Get Return Type」直指 TypeScript 内置工具类型ReturnTypeT其标准定义本身就是T extends (...args: any[]) infer R ? R : never——本题的核心就是让我们亲手写出这个定义。核心知识点条件类型与inferinfer的定位infer关键字只能出现在条件类型的extends分支中用于在类型匹配成功时声明一个待推断的类型变量。它的工作方式类似类型层面的「解构赋值」只要被检测的类型结构与模式匹配infer所在位置的具体类型就会被捕获到变量中供true分支使用。以本题为例函数类型在 TypeScript 中具有统一的形态——参数列表与返回值type MyReturnTypeT T extends (...args: any[]) infer R ? R : never逐段拆解T extends (...args: any[]) ...先判断T是否是一个函数类型。(...args: any[]) ...表示「接受任意数量、任意类型参数」的函数any[]确保了它对所有函数签名都成立。infer R匹配成功后将函数返回值的类型捕获到R中。infer与函数签名的右侧绑定因此R提取的正是返回类型。? R : never匹配成功返回R若T不是函数类型则落入never分支表示「无返回值类型可取」。为什么参数必须是...args: any[]标准库ReturnType的实现同样写作(...args: any[]) infer R。若改用unknown[]则无法保证任意函数都能被该签名匹配例如带有具体参数类型的函数与(...args: unknown[]) ...之间并不满足协变兼容关系从而导致推断失败。any在这里扮演的是「通配参数」角色这与本仓库其他题目中频繁出现的(...args: any[])模式是一致的。从模板到实现完整解题过程仓库为本题提供的起点模板位于 template.ts内容仅有一行占位符type MyReturnTypeT any将占位符any替换为条件类型 infer的完整实现即可通过全部用例type MyReturnTypeT T extends (...args: any[]) infer R ? R : never对示例中的fn应用该类型typeof fn展开为函数类型(v: boolean) 1 | 2该类型与(...args: any[]) infer R匹配返回值位置上的1 | 2被捕获为R最终MyReturnTypetypeof fn求值为1 | 2与题目预期一致。测试用例逐条解析本题的验证脚本位于 test-cases.ts共 7 条断言覆盖了六类典型场景。所有断言均借助type-challenges/utils中的Equal与Expect工具其定义在 utils/index.d.ts进行严格类型等价校验type cases [ ExpectEqualstring, MyReturnType() string, ExpectEqual123, MyReturnType() 123, ExpectEqualComplexObject, MyReturnType() ComplexObject, ExpectEqualPromiseboolean, MyReturnType() Promiseboolean, ExpectEqual() foo, MyReturnType() () foo, ExpectEqual1 | 2, MyReturnTypetypeof fn, ExpectEqual1 | 2, MyReturnTypetypeof fn1, ]用例输入函数类型期望结果考察点1() stringstring基础类型返回2() 123123字面量类型被完整保留3() ComplexObjectComplexObject复杂对象结构原样返回4() PromisebooleanPromiseboolean不展开Promise内部类型5() () foo() foo返回值为函数时保留完整函数签名6typeof fn布尔参数1 \| 2联合返回类型7typeof fn1双参数含any1 \| 2多参数函数不受参数影响其中ComplexObject定义在测试文件底部type ComplexObject { a: [12, foo] bar: hello prev(): number }两个值得注意的边界用例 4 说明本题不涉及Promise解包MyReturnType() Promiseboolean期望的正是Promiseboolean本身而非boolean。这是ReturnType与Awaited的分工差异——解包Promise属于仓库中另一道题目 00189Easy Awaited的范畴两者互为补充。用例 5 验证函数类型可被整体捕获当函数返回另一个函数时infer R捕获的是完整的() foo签名而不是其返回的字面量foo这体现了「一层推断只做一层提取」的语义。运行与验证方式本仓库是一个 pnpm workspacepackageManager: pnpm8.12.1见根目录 package.jsontype-challenges/utils通过workspace:*协议链接配置见根目录 pnpm-workspace.yaml 与 tsconfig.base.json。你可以在 template.ts 中填入上述实现使用tsc --noEmit对该题目录做类型检查观察 test-cases.ts 中的断言是否全部通过或前往题目对应在线评测环境README 中的 도전하기/Take the Challenge 链接提交你的实现由平台执行同样的用例校验。延伸思考infer的复用本题是掌握infer的入门钥匙同一模式在本仓库大量进阶题目中反复出现ParametersT用infer P捕获函数参数元组、ReturnTypeT用infer R捕获返回值二者本质都是「对函数签名做模式匹配」。更进一步infer还能用于递归字符串处理如 Trim、Replace 系列、元组推导如 Last、Pop以及联合类型展开等场景本仓库的 guides 目录即为此类知识点的进阶导航。可以说吃透本题的条件类型 infer组合就为后续中等乃至困难难度的类型体操题打牢了地基。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐Fizzy 项目 ReactionsBoostAPI 实战指南卡片与评论的快捷回应体系Fizzy 项目 ReactionsBoostAPI 实战指南卡片与评论的快捷回应体系 本指南以 Fizzy 仓库的 API 文档 docs/api/se示例工程在 type-challenges 中实现 MyReturnType用 infer 条件类型提取函数返回类型在 type challenges 中实现 MyReturnType用 infer 条件类型提取函数返回类型 本篇技术指南以 type challenges示例工程TypeScript 函数返回值类型推断从 The Concise TypeScript Book 的 Type from Func Return 到 ReturnType 与条件类型提取TypeScript 函数返回值类型推断从 The Concise TypeScript Book 的 Type from Func Return 到 R文档教程上一篇WPF 是什么解析 Windows Presentation Foundation 与 Modern .NET 的演进以 WPF UI 开源库为佐证下一篇Plate 富文本编辑器 Marks 渲染热路径优化pipeRenderLeaf / pipeRenderText 的混合激活扫描批次创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表