如何用TypeScript提取对象所有唯一叶子值的类型?
实现提取树形对象叶子值的联合类型泛型
Leaves 给定树形结构的常量对象(叶子节点为唯一字面量值):
const Tree = { Branch1: { Leaf1: '1', SubBranch1: { SubLeaf: '11' } }, Branch2: { Leaf2: '2', SubBranch2: { SubLeaf: '21' } } as const };
需要实现泛型Leaves<typeof Tree>,使其返回所有叶子值的联合类型'1' | '11' | '2' | '21'。
泛型实现
通过递归条件类型遍历树形结构,判断节点是否为叶子:
type Leaves<T> = T extends null | undefined ? never : T extends Record<string, infer U> ? Leaves<U> : T;
验证结果
用该泛型处理typeof Tree:
type TreeLeaves = Leaves<typeof Tree>; // 类型推断结果:'1' | '11' | '2' | '21'
关键说明
as const的必要性:必须给Tree添加as const断言,让TypeScript保留叶子节点的字面量类型;若省略,叶子值会被推断为宽泛的string类型,最终Leaves结果也会是string而非具体的字面量联合类型。- 递归逻辑:
- 先排除
null和undefined,避免无效递归; - 若当前类型是对象(用
Record<string, infer U>匹配),则递归处理对象的属性类型U; - 若当前类型不是对象,说明是叶子节点,直接返回该类型。
- 先排除
扩展:支持数组节点
如果树形结构包含数组,可扩展泛型支持数组元素的递归处理:
type Leaves<T> = T extends null | undefined ? never : T extends (infer U)[] ? Leaves<U> : T extends Record<string, infer U> ? Leaves<U> : T;
示例验证:
const TreeWithArray = { Branch: { Leaves: ['a', 'b'], SubBranch: { Leaf: 'c' } } as const }; type TreeWithArrayLeaves = Leaves<typeof TreeWithArray>; // 类型推断结果:'a' | 'b' | 'c'
内容的提问来源于stack exchange,提问作者Michael Colesnic
相关产品推荐
相关产品推荐

