示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载导读本文围绕 type-challenges 中编号 00018 的初级题目「Length of Tuple」展开目标是在不借助任何运行时逻辑的前提下实现一个泛型类型LengthT使其能够返回任意元组Tuple的字面量长度。通过阅读本文你将掌握元组类型与readonly元组的本质区别、T[length]索引访问类型在元组上的特殊行为以及如何用ts-expect-error与Equal断言验证类型实现的正确性。一、题目速览原题要求题目出处为 questions/00018-easy-tuple-length/README.ja.md标签为#tuple难度为easy见 info.yml 中的difficulty: easy与tags: tuple。原题要求非常简洁实现一个接收元组T、返回该元组长度的类型LengthT。题目给出的示例type tesla [tesla, model 3, model X, model Y] type spaceX [FALCON 9, FALCON HEAVY, DRAGON, STARSHIP, HUMAN SPACEFLIGHT] type teslaLength Lengthtesla // expected 4 type spaceXLength LengthspaceX // expected 5虽然题目描述只有短短一句话但要在类型层面算出元组长度背后涉及 TypeScript 元组类型系统的若干关键机制。接下来我们逐步拆解。二、前置知识元组、readonly元组与T[length]2.1 元组Tuple与数组Array的差异在 TypeScript 中元组是一种定长、元素类型可各不相同按位置声明的数组类型。例如[tesla, model 3, model X, model Y]这个字面量如果写成const arr [tesla, model 3, model X, model Y]其推断类型是string[]——一个普通数组长度未知元素的类型被统一收窄为string。而一旦加上as constconst tesla [tesla, model 3, model X, model Y] as consttypeof tesla就变成了一个只读元组type Tesla readonly [tesla, model 3, model X, model Y]这正是 test-cases.ts 中的写法const tesla [tesla, model 3, model X, model Y] as const const spaceX [FALCON 9, FALCON HEAVY, DRAGON, STARSHIP, HUMAN SPACEFLIGHT] as const2.2 元组的length是字面量数字类型对元组类型使用索引访问T[length]TypeScript 会返回精确的字面量数字类型如4、5而不是宽泛的number。因为元组的长度在编译期是确定的类型系统将其编码在类型结构中。对普通数组如string[]执行T[length]则只能得到number——数组长度在类型层面未知。这是区分元组与数组在类型层面最重要的观测点之一。三、解法推导从占位符到正确实现仓库给出的 template.ts 只有一个占位实现type LengthT any把any换成正确答案最直接且最常见的写法是type LengthT extends readonly unknown[] T[length]对题目示例验证type tesla [tesla, model 3, model X, model Y] type spaceX [FALCON 9, FALCON HEAVY, DRAGON, STARSHIP, HUMAN SPACEFLIGHT] type teslaLength Lengthtesla // 4 type spaceXLength LengthspaceX // 53.1 为什么约束必须是readonly unknown[]约束T extends readonly unknown[]有两个关键作用限定入参必须是元组unknown[]及readonly unknown[]是元组的超类型任何具体元组都能满足该约束兼容as const产生的只读元组readonly修饰符是必需的。如果写成T extends unknown[]那么Lengthtypeof tesla会因为tesla是只读元组readonly [...]而无法赋值给可变数组约束直接编译报错。3.2 为什么不能放宽成{ length: number }一种直觉上的偷懒写法是把约束放宽为任何带length属性的对象type LengthT extends { length: number } T[length]这种写法对Lengthhello world不会报错——因为字符串恰好拥有length: number属性结果会被推断为number而非精确长度。这直接违背了测试用例中的预期见下文第四节所以必须用元组约束来精确限定入参。四、测试用例验证Equal、Expect与ts-expect-error4.1 正面断言test-cases.ts 定义了如下类型级测试import type { Equal, Expect } from type-challenges/utils type cases [ ExpectEqualLengthtypeof tesla, 4, ExpectEqualLengthtypeof spaceX, 5, // ts-expect-error Length5, // ts-expect-error Lengthhello world, ]其中ExpectT extends true T与严格相等判定EqualX, Y都定义在 utils/index.d.ts 中。Equal的实现采用了函数参数位置协变比较的技巧export type EqualX, Y (T() T extends X ? 1 : 2) extends (T() T extends Y ? 1 : 2) ? true : false这套间接比较机制能够识别出any等容易被extends直接比较所掩盖的差异从而保证ExpectEqual...是严格类型相等断言。只有当Lengthtypeof tesla精确等于4、Lengthtypeof spaceX精确等于5时两个Expect才分别成立。4.2 负面断言测试中的两处// ts-expect-error是本题的隐藏考点Length5数字类型没有length属性也不满足元组约束必须报错Lengthhello world字符串虽然有length属性但它不是元组同样必须报错。ts-expect-error要求紧邻的下一行确实产生类型错误如果实现过于宽松例如 3.2 节那种{ length: number }约束第二处断言会在编译期直接报未预期的错误测试即不通过。这正是约束必须写成readonly unknown[]而非任何带 length 的对象的硬性证据。五、深入理解元组结构、keyof与T[length]的原理5.1 元组类型的内部结构从类型结构看元组[a, b, c]等价于type T { 0: a 1: b 2: c length: 3 }因此对元组使用keyof得到的是0 | 1 | 2 | length而T[length]正是利用这一结构直接取到代表长度的数字字面量3。理解了这一点就能明白为什么Length的实现如此简短却准确它不是在计算而是在读取类型系统已经编码好的结构信息。5.2 为什么简单却值得练习本题位于题库 questions 目录的 early 阶段编号 00018紧跟在 First、Tuple Length 相关基础题之后它的价值在于强制理解as const与readonly元组这是后续大量题目如Deep Readonly、Readonly 2等的共同前置知识培养用约束驱动推导的思维先看测试用例对入参和出参的要求元组入参、字面量长度出参、拒绝字符串与数字再反推泛型约束怎么写。5.3 与普通数组的对比如果传入的不是元组而是普通数组类型type Nums number[] type N LengthNums // number而非某个具体数字因为普通数组长度在类型层面未知T[length]只能得到number。这也是元组类型在类型编程中可精确计算的根本原因所在。六、运行与验证方式本仓库是一个纯类型层面的题库无需构建产物。要验证你的实现可以直接在支持 TypeScript 的编辑器中打开 test-cases.ts配合仓库根目录的 tsconfig.base.json开启了strict模式进行类型检查也可以把实现粘贴到 TypeScript Playground 中手动验证Lengthtesla的类型推断结果。完成题目后可在同一目录下对照 README.zh-CN.md 等多语言版本复习题意并继续挑战#tuple标签下的其他题目。七、小结「Length of Tuple」的完整解如下type LengthT extends readonly unknown[] T[length]约束readonly unknown[]保证了入参是元组含只读元组同时拒绝数字与字符串索引访问T[length]直接利用元组类型结构返回精确的字面量长度测试用例通过Equal/Expect做严格相等断言通过ts-expect-error做负面断言完整锁定了实现的行为边界。这一题虽小却同时触及了元组、只读修饰符、字面量数字类型与类型约束四条 TypeScript 类型系统的核心线索是进入类型编程世界的理想起点。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐Length of Tuple在 type-challenges 中用 T[length] 精确获取元组长度Length of Tuple在 type challenges 中用 T length 精确获取元组长度 本文以 type challenges 仓库的示例工程获取元组长度type-challenges 第 18 题 Length\T\ 的类型体操实战解析获取元组长度type challenges 第 18 题 Length\T\ 的类型体操实战解析 本指南以 type challenges 仓库中第 18示例工程pwndbg kdmesg 命令详解在 GDB/LLDB 中读取 Linux 内核环形缓冲区pwndbg kdmesg 命令详解在 GDB/LLDB 中读取 Linux 内核环形缓冲区 导读 kdmesg 是 pwndbg 内核调试命令族Comma示例工程上一篇Fluentd与Hadoop、Spark大数据平台集成终极指南下一篇SlyceMessaging样式主题定制创建独特品牌风格的聊天界面设计指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考