尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TS 类型体操:一个递归模型,拆完 type-challenges 八道 Medium 题

TS 类型体操:一个递归模型,拆完 type-challenges 八道 Medium 题 TS 类型体操一个递归模型拆完 type-challenges 八道 Medium 题【免费下载链接】weekly前端精读周刊。帮你理解最前沿、实用的技术。项目地址: https://gitcode.com/GitHub_Trending/we/weeklyTypeScript 类型体操里最劝退的往往不是语法而是条件类型 infer 递归三连。我把 type-challenges 题库的 Medium 17~24 这八道题Permutation、LengthOfString、Flatten、AppendToObject、Absolute、StringToUnion、Merge、KebabCase逐道抠完发现它们共用一套很土的递归模型把输入拆出一个最小单元存进一个累加器让输入变小再递归直到空了取累加器——说白了就是把 JS 里的一个for循环搬到了类型层面。这篇 type-challenges 题解按这套模型把八道题分成三组拆完不预设你读过别的解法每到一个卡点我会先把你以为会怎样摆出来再告诉你哪里想当然最后给正解。一、先把 for 循环搬进类型层拆、存、缩你写 JS 循环大概是这个形状let acc: any[] []; for (let i 0; i input.length; i) { acc.push(process(input[i])); // 存一个 } return acc;类型层面没有let但有等价物——带默认值的第二个泛型。它在递归里扮演的就是这个acc我后面会反复叫它累加器。把循环翻译成类型骨架是// 把逐项处理翻译成类型递归 type LoopFirst, Rest, Acc extends unknown[] [] Rest extends [infer First, ...infer R] ? LoopFirst, R, [...Acc, First] // 存一个Acc缩一个R : Acc; // 空了取累加器三个角色后面八题全是它的变体先记住名字First这一步拆出来的最小单元Acc累加器默认值[]或never或把中间态攒着R缩小后的输入递归它模型立完下面按输入长什么样分三组。二、输入是联合类型逼出分配律排满每一种可能题干type perm PermutationA | B | C; // [A,B,C] | [A,C,B] | [B,A,C] | [B,C,A] | [C,A,B] | [C,B,A]破题卡点是怎么让一个入参递归下去。TS 有个分配行为——当一个裸泛型出现在T extends U ? A : B里且T本身是联合类型时TS 会把T拆成单个成员分别判断再把结果用|拼回来type IsXT T extends x ? 1 : 2; type R IsXa | b; // IsXa | IsXb 2Permutation 正需要这个拆递归时把A|B|C摊成A、B、C各自往下走。但分配只在裸泛型上触发而题面只给了一个入参。解法是再声明一个默认值等于第一个的泛型凑出第二个位置让分配有处下手// T当前要占坑的成员U还没排完的全部成员默认 T type PermutationT, U T [T] extends [never] ? [] // 没人可排终止 : T extends U ? [T, ...PermutationExcludeU, T] // 占 T 的坑剩余成员继续排 : [];这里有个 想当然的坑。终止条件很多人会写成T extends never ? [] : ...跑出来直接never或者压根不展开。原因TS 对T extends ...做联合分配时有一条特例——当T恰好是never它会跳过分配、把T原样返回你的三元判断根本没执行。正解是用元组把T包一层[T] extends [never]。包上之后分配行为被挡掉判断才真正跑起来。这一招后面还会用到先记住判 never 一律用[T] extends [never]。手工展开一层PermutationA|B|CTA|B|C 对 T 分配 ─┬─ PermutationA,A|B|C ├─ PermutationB,A|B|C └─ PermutationC,A|B|C 取第一支 PermutationA,A|B|C A extends A|B|C → [A, ...PermutationB【免费下载链接】weekly前端精读周刊。帮你理解最前沿、实用的技术。项目地址: https://gitcode.com/GitHub_Trending/we/weekly创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表