示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载本文基于开源仓库 type-challenges 中的 medium 难度题目「Public Type」展开完整解析如何实现一个工具类型PublicTypeT移除给定对象类型T中所有以_开头的键保留其余公开属性包括readonly、可选属性以及值为_开头的字符串的键。读完本文你将掌握基于映射类型与键重映射Key Remapping实现对象键过滤的完整套路并能通过仓库自带的测试用例test-cases.ts验证解法的正确性。题目概述与约束题目定义位于 README.md核心需求只有一句话Remove the key starting with_from given typeT.题目给出的模板文件 template.ts 如下type PublicTypeT extends object any即需要你把any替换为真正的实现并满足 info.yml 中声明的元信息难度为medium标签为object-keys对象键操作。题目的核心语义可归纳为三点只移除键名key以_开头的属性保留其余属性的值类型属性值本身是否以_开头例如字符串_g不影响过滤逻辑过滤只看键名对象上的修饰符readonly、可选?必须原样保留不能因为过滤而丢失。测试用例驱动的边界条件仓库为该题提供了 7 组测试用例来自 test-cases.ts它们共同刻画了本题的所有边界条件type cases [ ExpectEqualPublicType{ a: number }, { a: number }, ExpectEqualPublicType{ _b: string | bigint }, {}, ExpectEqualPublicType{ readonly c?: number }, { readonly c?: number }, ExpectEqualPublicType{ d: string, _e: string }, { d: string }, ExpectEqualPublicType{ _f: () bigint[] }, {}, ExpectEqualPublicType{ g: _g }, { g: _g }, ExpectEqualPublicType{ __h: number, i: unknown }, { i: unknown }, ]逐条拆解这些用例可以得到明确的验收标准用例输入期望输出考察点1{ a: number }{ a: number }不含_键时原样返回2{ _b: string \| bigint }{}唯一键以_开头整个对象被清空3{ readonly c?: number }{ readonly c?: number }readonly与可选修饰符必须保留4{ d: string, _e: string }{ d: string }混合场景只移除_开头的键5{ _f: () bigint[] }{}值类型为函数同样要移除6{ g: _g }{ g: _g }值是_g字符串但键名不是_开头必须保留7{ __h: number, i: unknown }{ i: unknown }双下划线开头的键也要移除unknown值正常保留其中用例 6 是初学者最容易踩坑的地方很多实现会用K extends \_${string}去匹配键名但若错误地把判断写到了值上就会误删{ g: _g }。正确的过滤对象永远是键而不是值。实现方案键重映射 模板字面量类型在 TypeScript 4.1 引入模板字面量类型与键重映射Key Remapping之后这类过滤任务可以非常优雅地完成。整体思路是使用keyof T取出所有键用as子句对每个键做重映射键名以_开头则映射为never从而从映射类型结果中剔除否则保留原键名重映射后键为never的属性会自动从生成的对象类型中被丢弃。一种可直接通过测试的实现如下type PublicTypeT extends object { [K in keyof T as K extends _${string} ? never : K]: T[K] }逐部分解读[K in keyof T]标准的同态映射类型遍历T的所有键as K extends \${string} ? never : K键重映射表达式。${string}是模板字面量类型匹配「以_开头、后接任意字符串」的键名匹配成功的键被映射为never其余键保留原名T[K]索引访问类型取每个属性的值类型同时天然保留readonly与可选修饰符对原类型做同态映射时修饰符会被继承。为什么never能实现删除键重映射中把键映射为never是官方推荐的对象键过滤方式。TypeScript 在计算映射类型结果时会跳过键为never的属性因此{ _b: string | bigint }这类输入会得到{}用例 2、5 的期望结果而修饰符与值类型不受影响用例 3。修饰符保留的底层机制用例 3 的readonly c?: number要求输出仍是{ readonly c?: number }这依赖映射类型的「同态」homomorphic特性当K in keyof T直接基于keyof T遍历时TypeScript 会自动继承源属性上的readonly和可选性。这也是为什么实现中不能写成[K in keyof T as ...]: T[K]之外的其他破坏性写法。深入值类型与键名的语义区分用例 6{ g: _g }期望输出仍是{ g: _g }说明本题只关心键的形态与值无关。如果你对「为什么_g作为值保留、_b作为键删除」感到困惑可以这样理解键匹配发生在映射类型的键位K上K extends \_${string} 判断的是键名字符串值匹配发生在值位T[K]上本题完全不涉及。这种「只看键、不看值」的设计让PublicType区别于其他常见的对象过滤工具OmitT, K按明确列出的键删除PickT, K按明确列出的键保留本题的PublicTypeT按键名的字符模式前缀_删除属于模式驱动的过滤。另外本仓库中还有一处与本题语义互补的练习RemoveIndexSignature 移除的是索引签名而不是以_开头的具名键读者可以对比体会「键过滤」的不同维度。变体与进阶思考如果题目扩展到「移除以_开头且不只一个下划线的键」例如__h只需把条件收紧type PublicTypeStrictT extends object { [K in keyof T as K extends _${string} ? never : K]: T[K] }如上所见由于\${string}已经覆盖了__h双下划线也是「以开头」的子串现有实现天然通过用例 7。若想只删除「恰好一个下划线开头」的键可改用${infer Rest}并结合对Rest不以 开头的判断但这是扩展需求不在本题验收范围内。再比如若想同时处理嵌套对象深层过滤可以递归调用自身type PublicTypeDeepT extends object { [K in keyof T as K extends _${string} ? never : K]: T[K] extends object ? PublicTypeDeepT[K] : T[K] }这是锦上添花的延伸本题原测试用例仅要求一层过滤。如何运行与验证本仓库是标准的 type-challenges 工程结构每道题都包含template.ts待实现模板与test-cases.ts验收用例。验证本题解法可遵循以下流程在 template.ts 中填入上述实现用例文件从 utils/index.d.ts 导入Equal与Expect两个断言工具类型——ExpectT extends true T要求传入的类型必须为true而EqualX, Y通过函数参数逆变位置的比对实现严格类型等价判断这正是 test-cases.ts 中每一行ExpectEqual...的校验原理在仓库根目录或utils子工程参见 utils/package.json使用安装了 TypeScript 5.x 的环境对该文件做类型检查若所有ExpectEqual...均通过则解法正确。仓库根目录的 package.json 使用 pnpm 管理依赖并声明了readme、build、generate、lint等脚本对于只验证单题的读者直接针对test-cases.ts运行tsc --noEmit类型检查即可得到反馈无需修改仓库任何文件。总结PublicTypeT是 type-challenges 中一道小而精的 medium 题目核心考点可总结为键重映射as子句是过滤对象键的标准手段映射为never即实现删除模板字面量类型\${string}负责匹配「以 开头」的键名模式同态映射类型自动保留readonly与可选修饰符保证过滤后对象结构语义不丢过滤对象是只看键、不看值的操作理解这一点就能避开{ g: _g }这类陷阱。掌握这一套路后你可以举一反三地实现按任意前缀、后缀或正则语义如 camelCase / snake_case过滤对象键的各种工具类型应对日常类型体操与库类型设计中常见的「去除私有/内部字段」需求。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐TypeScript 类型挑战解析实现 OptionalKeysT 提取对象的所有可选键TypeScript 类型挑战解析实现 OptionalKeysT 提取对象的所有可选键 导读 OptionalKeysT 是 type challeng示例工程告别TypeScript私有属性污染PublicType类型实战指南告别TypeScript私有属性污染PublicType类型实战指南 你是否曾为TypeScript对象中以下划线开头的私有属性烦恼这些属性在类型定义中常常示例工程TypeScript 类型挑战实现 ReplaceKeys按需替换联合类型中的对象键TypeScript 类型挑战实现 ReplaceKeys按需替换联合类型中的对象键 本指南围绕 type challenges 第 1130 号中等难度题示例工程上一篇3步跑通TagStudio不挪动一个文件的标签式文件管理系统下一篇免费开源AMD Ryzen处理器终极调试工具SMUDebugTool完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?