TypeScript中如何实现递归提取节点深层后代类型的工具类型?
递归后代类型提取实现
实现思路
工具类型通过递归计算节点的全部深层后代,核心规则非常简单:
- 文本节点是树结构的叶子节点,不存在任何后代,直接返回
never作为递归终止条件 - 元素节点的全部后代,是「直接浅层子节点类型」和「所有直接子节点的深层后代类型」的联合结果
完整代码
// 基础节点类型定义 type Text = { text: string } type Element = { children: Node[] } type Node = Element | Text // 已有的浅层子节点提取工具类型 type ChildOf<N extends Node> = N extends Element ? N['children'][number] : never // 递归深层后代提取工具类型 type DescendantOf<N extends Node> = N extends Text ? never : ChildOf<N> | DescendantOf<ChildOf<N>> // 自定义测试节点类型 type A = { children: Text[] } type B = { children: A[] } type C = { children: B[] }
类型匹配验证
完全符合预期的计算结果:
DescendantOf<A>:结果为TextDescendantOf<B>:结果为A | TextDescendantOf<C>:结果为A | B | TextDescendantOf<Text>:结果为never
实现注意事项
- TypeScript 对条件类型的联合自动分发机制,会让工具类型天然支持传入联合类型的节点,不需要额外编写分发逻辑
- 递归终止条件明确:只要递归链走到Text类型,就会停止计算返回never,不会出现无限递归
- 类型计算过程和JS层面的树遍历逻辑完全一致,和DOM节点的遍历行为匹配
内容的提问来源于stack exchange,提问作者Ian Storm Taylor
相关产品推荐
相关产品推荐

