TypeScript如何获取对象叶子节点的所有父路径?
解决TypeScript中PropertyPath叶子节点父路径的自动推导问题
我们已经有了能提取对象叶子节点路径的PropertyPath类型(比如针对Track接口,能得到"album.track.id"这类完整叶子路径),现在需要自动推导这些叶子节点的父路径(比如"album.track"),不需要手动传入叶子键,同时避免之前把K设为string时,Head只匹配第一个点前内容的问题。
具体实现代码
// 先定义已有的PropertyPath类型(用来提取所有叶子节点路径) type PropertyPath<T> = T extends object ? { [K in keyof T]-?: K extends string | number ? `${K}` | `${K}.${PropertyPath<T[K]>}` : never }[keyof T] : never; // 核心:自动推导叶子节点的父路径,无需额外传参 type ParentPath<T> = PropertyPath<T> extends `${infer Head}.${infer Tail}` ? // 判断Tail是否还有层级(即是否是叶子节点的最后一段) Tail extends `${string}.${string}` ? // 递归处理子节点的父路径,拼接完整父路径 `${Head}.${ParentPath<Extract<T, { [key in Head]: any }>[Head]>}` : // 已经到叶子节点的上一层,直接返回Head Head : // 根级叶子节点没有父路径,返回never(可按需改成空字符串) never; // 测试用的Track接口 interface Track { id: string; album: { track: { id: number; title: string; }; name: string; }; title: string; } // 测试结果:得到所有叶子节点的父路径集合 type TrackParentPaths = ParentPath<Track>; // 输出类型为:"album" | "album.track" | never
实现逻辑说明
- 递归拆解路径:利用TypeScript模板字符串的类型推断,把完整叶子路径拆分为
Head(当前层级键)和Tail(剩余路径)。 - 判断叶子层级:如果
Tail本身包含点,说明当前路径还不是叶子的直接父路径,递归处理Head对应的子类型,拼接出完整的父路径。 - 终止条件:当
Tail没有点时,说明Head就是叶子节点的直接父路径,直接返回。 - 根级叶子处理:对于根节点的叶子(比如
Track的id、title),它们没有父路径,这里返回never(也可按需改成空字符串或其他默认值)。
这个方案彻底解决了之前设K为string时只匹配第一个点的问题,通过递归遍历每一层路径,正确推导所有叶子节点的完整父路径。
内容的提问来源于stack exchange,提问作者striderhobbit
相关产品推荐
相关产品推荐

