示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载本篇指南基于 type-challenges 仓库中的00014-easy-first挑战题目原文围绕如何用 TypeScript 类型系统从数组/元组中提取首元素类型展开。你将掌握FirstT泛型的约束写法、索引访问类型Indexed Access的使用、空数组边界处理并通过仓库自带的测试用例验证答案的正确性。完成此题后你还可以顺势挑战其姊妹题 Last of Array进一步巩固元组模式匹配的思维。一、题目概述从一个数组提取首元素类型本挑战属于 type-challenges 的easy쉬움难度关卡核心标签为array详见 info.yml作者是 Anthony Fuantfu对应题号14。题目要求原文为韩文见 README.ko.md实现一个接收数组元组T并返回其第一个元素类型的泛型FirstT。示例type arr1 [a, b, c] type arr2 [3, 2, 1] type head1 Firstarr1 // expected to be a type head2 Firstarr2 // expected to be 3从这个例子可以看出FirstT不是取数组的运行时首元素而是在类型层面推导出元组的首元素类型对[a, b, c]得到字面量类型a对[3, 2, 1]得到字面量类型3。二、起点模板与题目约束在动手之前先看仓库中提供的起点模板 template.tstype FirstT extends any[] any模板已经把两件事交代清楚了泛型参数必须被约束为数组T extends any[]。这保证了传入First的一定是数组或元组类型而不是字符串、对象等。返回值处是any这是留给解题者填充的空位需要替换为真正提取首元素类型的逻辑。也就是说答案的核心任务只有一个把any替换为取T的第一个元素类型的类型表达式。三、解法一通过索引访问类型 T[0]最直接的思路是使用 TypeScript 的索引访问类型Indexed Access Typetype FirstT extends any[] T[0]对于元组[a, b, c]T[0]会精确得到首元素类型a对于[3, 2, 1]得到3。这正是题目示例期望的结果。需要注意的一个边界场景是空元组First[]中T[0]无法命中任何元素TypeScript 会将其推导为never。这恰好与仓库测试用例 test-cases.ts 中的断言一致ExpectEqualFirst[], never,所以T[0]这一写法天然覆盖了空数组场景无需额外处理。四、解法二通过 infer 模式匹配提取首元素另一种常见思路是利用条件类型 infer从元组中拆出首元素type FirstT extends any[] T extends [infer F, ...any[]] ? F : never它的工作原理是T extends [infer F, ...any[]]将T与至少含一个元素的元组进行模式匹配匹配成功时F被推断为元组的首元素类型直接返回F匹配失败即空元组[]时走never分支。两种写法在本题的测试用例下结果等价T[0]更简洁infer写法则更贴近后续 medium/hard 关卡中频繁使用的元组拆分思维例如 Last of Array 就需要用到[...infer Rest, infer L]的形式。五、用仓库测试用例验证答案type-challenges 的每个关卡都配有test-cases.ts作为在线判题依据。本题的测试用例包含 4 条正向断言与 2 条负向断言import type { Equal, Expect } from type-challenges/utils type cases [ ExpectEqualFirst[3, 2, 1], 3, ExpectEqualFirst[() 123, { a: string }], () 123, ExpectEqualFirst[], never, ExpectEqualFirst[undefined], undefined, ] type errors [ // ts-expect-error FirstnotArray, // ts-expect-error First{ 0: arrayLike }, ]这些用例从多个维度约束了答案的正确性函数类型作为元素First[() 123, { a: string }]必须精确返回函数类型() 123说明首元素可以是任意类型不能被宽化成Function空数组边界First[]必须是neverundefined也是合法元素First[undefined]应返回undefined类型本身负向约束FirstnotArray和First{ 0: arrayLike }必须报错——这正是T extends any[]约束发挥的作用它阻止了把字符串、对象等非数组类型传入First。注意{ 0: arrayLike }虽然按索引可以访问到arrayLike但它不是数组因此同样被拒绝。type-challenges/utils是仓库 workspace 内的工具包其中 utils/index.d.ts 定义了Equal和Expect等断言工具。EqualX, Y采用函数参数逆变比较的经典技巧实现严格相等判断只有两侧类型完全一致时才返回true因此你的答案必须与期望类型精确相等不能只是兼容。六、本地运行与在线挑战方式本仓库使用 pnpm 管理依赖见根目录 package.json包管理器为pnpm8.12.1。如果你想在本地体验在线判题需要先安装依赖pnpm install之后可以直接在编辑器中打开questions/00014-easy-first/template.ts填入答案后通过 TypeScript 类型检查例如npx tsc --noEmit验证测试是否通过。更推荐的方式是直接访问该题的在线 PlaygroundREADME.md 中提供了挑战入口在浏览器里即时验证答案并可以查看社区提交的多种解题思路。七、延伸姊妹题 Last of Array本关卡在 info.yml 中声明了关联题15即 Last of Arraymedium 难度。它的模板是type LastT extends any[] any取最后一个元素无法再用T[0]这种固定索引而需要配合infertype LastT extends any[] T extends [...any[], infer L] ? L : never可以看出First是理解元组 infer 模式匹配的入门题先掌握[infer F, ...any[]]从头部拆解再学会[...any[], infer L]从尾部拆解后续的 Pop、Shift 等数组操作挑战就都有了基础。小结FirstT看似简单却浓缩了类型挑战的三项基本功用extends any[]约束泛型参数、用T[0]或infer从元组中提取元素类型、用never处理空数组边界。对照 template.ts 与 test-cases.ts 完成并验证答案你就迈出了 type-challenges 数组系列类型编程的第一步。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐CUDA 加速 Black-Scholes 期权定价cuda-samples BlackScholes 示例源码级解析CUDA 加速 Black Scholes 期权定价cuda samples BlackScholes 示例源码级解析 导读 本文基于 NVIDIA CUDA示例工程TypeScript 类型挑战 00014实现 First\T\ 获取数组第一个元素类型TypeScript 类型挑战 00014实现 First\T\ 获取数组第一个元素类型 本篇文章围绕 type challenges 仓库中编号 0001示例工程type-challenges 第 15 题「最后一个元素 Last of Array」用类型体操实现数组尾元素提取type challenges 第 15 题「最后一个元素 Last of Array」用类型体操实现数组尾元素提取 type challenges 是一个带示例工程上一篇【亲测免费】 探索游戏新边界Apollo Save ToolPS4- 玩家的宝藏工具箱下一篇MAA自动公招怎么配置三步搞定一键招募加急许可刷光券创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考