ARTICLE DETAIL

资讯详情

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

type-challenges 中等挑战 2070:用模板字面量类型与 infer 实现 Drop Char

type-challenges 中等挑战 2070:用模板字面量类型与 infer 实现 Drop Char 示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载type-challenges 是一套带在线评测系统的 TypeScript 类型体操题库项目说明。本文聚焦其中第 2070 号中等难度挑战Drop Char从字符串类型中剔除指定字符通过条件类型、模板字面量类型template literal types与infer三个核心工具的组合实现一个纯粹的类型层面的字符串处理函数。读完本文你将掌握模板字面量类型的递归匹配套路理解infer在模式匹配中的角色并能够独立解出同类的字符串类型操作题。挑战概览题目要求与已知条件根据 questions/02070-medium-drop-char/README.md题目定义如下难度中等medium标签template-literal、infer作者CaptainOfPhB目标定义一个类型DropCharS, C把字符串S中出现的所有字符C剔除返回处理后的字符串类型。题面给出的示例type Butterfly DropChar b u t t e r f l y ! , // butterfly!也就是说S与C都是字符串字面量类型我们要剔除S中所有等于C的字符保留其余字符并保持原有顺序。题目的元数据记录在 questions/02070-medium-drop-char/info.yml 中difficulty: medium、tags: template-literal, infer并注明related: 2059即 Hard 难度的 Drop String 挑战。起点模板与测试用例先看清验收标准仓库为每个挑战都提供了起始模板待填空的占位类型与测试用例。本题的 template.ts 非常简单type DropCharS, C any我们的任务就是把any替换为真正可用的类型逻辑同时保证全部测试通过。测试用例位于 test-cases.tsimport type { Equal, Expect } from type-challenges/utils type cases [ // ts-expect-error ExpectEqualDropCharbutter fly!, , butterfly!, ExpectEqualDropCharbutter fly!, , butterfly!, ExpectEqualDropCharbutter fly!, !, butter fly, ExpectEqualDropChar butter fly! , , butterfly!, ExpectEqualDropChar b u t t e r f l y ! , , butterfly!, ExpectEqualDropChar b u t t e r f l y ! , b, u t t e r f l y ! , ExpectEqualDropChar b u t t e r f l y ! , t, b u e r f l y ! , ]逐条解读这些用例可以提炼出本题的验收要求用例输入S剔除字符C期望结果考察点butter fly!空字符串类型错误ts-expect-error空字符串作为剔除字符应被拒绝butter fly! butterfly!基础空格剔除butter fly!!butter fly剔除普通字符 butter fly! butterfly!首尾连续空格全部剔除 b u t t e r f l y ! butterfly!所有目标字符出现处都剔除 b u t t e r f l y ! b u t t e r f l y ! 只剔指定字符其他字符与空格保留 b u t t e r f l y ! t b u e r f l y ! 多次出现全部剔除其中用到的Equal与Expect工具类型定义在 utils/index.d.tsExpectT extends true TEqualX, Y通过函数的参数逆变比较(T() T extends X ? 1 : 2) extends (T() T extends Y ? 1 : 2)严格判断两个类型是否相等。这意味着解法必须产生与期望完全相同的字符串字面量类型任何多出的空格、丢失的字符都会导致测试失败。核心解法条件类型 infer 模板字面量递归题目标签template-literal与infer已经给出了解题方向。TypeScript 4.1 引入的模板字面量类型允许在类型层面用${}拼接字符串并且可以与infer配合做模式匹配 提取子串type DropCharS extends string, C extends string S extends ${infer Head}${infer Tail} ? Head extends C ? DropCharTail, C : ${Head}${DropCharTail, C} : S逐层分析这个解法的执行流程递归终止条件当S extends${infer Head}${infer Tail} 不成立时说明S已退化到空字符串或其他无法再拆分的字面量此时直接返回S本身。拆解字符串${infer Head}${infer Tail}会把字符串拆成首字符 剩余部分。这里Head被推断为单个字符Tail为剩余子串。判断是否命中用条件类型Head extends C判断当前字符是否就是要剔除的字符。注意 TypeScript 的条件类型在联合类型上是分布式的distributive conditional types但由于本题中C固定为一个字面量、Head每次匹配到单一字符这里表现为一次普通的判断。剔除或保留命中则直接丢弃Head只递归处理Tail未命中则把Head保留拼接到递归结果的前面。逐字符累积递归不断推进Tail最终完整遍历整个字符串所有命中字符被移除其余字符按原顺序重组。边界情况为什么空字符串要被拒绝第一个测试用例特意标注了ts-expect-error// ts-expect-error ExpectEqualDropCharbutter fly!, , butterfly!ts-expect-error要求下一行代码必然产生编译错误。也就是说设计上DropChar的第二参数C不允许传入空字符串。为此可以对类型参数加上约束type DropCharS extends string, C extends string ...这样C必须是string类型而空字符串字面量本身就是string的子类型直接写C extends string仍会放行空串。更严谨的做法是显式约束C必须是非空字符串type DropCharS extends string, C extends string { length: 1 } ...利用{ length: 1 }把C限定为恰好一个字符长度的字面量。这样DropCharbutter fly!, 就会因不满足约束而报错正好满足ts-expect-error的期望同时 、b、!这些单字符串都能通过约束。这也是对从字符串中剔除一个指定字符这一题意的类型级强化。从源码结构看为什么这里用模板字面量 infer在类型层面处理字符串TypeScript 提供了两条路径字符串字面量联合 /keyof工具适合对象键名、枚举等有限集合不适合任意内容字符串模板字面量类型 infer可以像正则一样对字符串做匹配并提取的递归拆解是本题这类任意字符串处理题目的标准解法。模板字面量类型在推断时的关键行为是${infer A}${infer B}对未知字符串做拆解时TypeScript 会优先让第一个infer捕获尽可能短的内容单字符剩余部分交给第二个infer因此Head/Tail的递归拆解是确定且可终止的。这也解释了为什么解法不需要额外的长度判断——递归天然会在字符串耗尽时落入终止分支。仓库的 guides/infer.md 与 guides/key-in.md 是官方为infer与key in主题准备的专项指南本题的标签与之一致可作为深入学习infer推导规则的配套资料。延伸进阶从 Drop Char 到 Hard 的 Drop Stringinfo.yml与 README 页脚都标注了关联挑战2059・Drop StringREADME.md难度 hard。两者的关系是一脉相承的Drop Char 只剔除一个字符而 Drop String 要剔除一组字符type Butterfly DropStringfoobar!, fb // ooar!Drop String 的测试用例test-cases.ts展示了更强的场景第二个参数本身是一个字符串其中每个字符都要被剔除。从源码结构看Drop String 的经典解法正是在 Drop Char 的思路上加一层外层递归先把R拆成字符对每个字符应用逐个剔除再递归处理下一个字符。也就是说学会 Drop Char 等于拿到了 Drop String 的一半解法这正是官方把两者设为关联题目的原因。如何验证你的解法type-challenges 的每个题目目录都自带test-cases.ts与template.ts验证方式与普通 TS 项目一致在 template.ts 中填入你的类型实现用tsc仓库 devDependencies 中锁定 TypeScript^5.3.3见 package.json对 test-cases.ts 做类型检查没有报错即代表全部Equal断言通过也可在 tsconfig.json 与 tsconfig.base.json 配置的严格模式下运行保证解法的类型安全性。补充一点本文给出的解法以每步拆单字符实现若想追求更紧凑的写法也可以利用模板字面量一次匹配更长片段如S extends${infer A}${C}${infer B} 直接按目标字符定位再对两侧递归核心原理仍是模板字面量匹配 infer 提取 条件类型分发 递归推进掌握本文的拆解思路后即可灵活变形。赞分享示例工程【免费下载链接】type-challengesCollection of TypeScript type challenges with online judge项目地址https://gitcode.com/GitHub_Trending/ty/type-challenges点击查看免费下载相关推荐type-challenges 中等题精解用模板字面量类型实现 CapitalizeTtype challenges 中等题精解用模板字面量类型实现 CapitalizeT 本篇文章基于开源仓库 type challengesCollect示例工程type-challenges 中等题 612用模板字面量类型实现 KebabCase 字符串转换type challenges 中等题 612用模板字面量类型实现 KebabCase 字符串转换 本文围绕 type challenges 仓库第 612示例工程type-challenges 中等题 298用模板字面量类型与递归实现 Length of Stringtype challenges 中等题 298用模板字面量类型与递归实现 Length of String 本文围绕 type challenges 题库中编示例工程上一篇终极指南5分钟掌握ncmdump轻松解锁网易云NCM加密音乐下一篇3分钟快速上手Windows版Spotify无广告体验完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表