TypeScript中的递归类型简析
// 定义一个简单的接口,表示一个可能的无限分类节点
interface CategoryNode {
id: number;
name: string;
parentId?: number; // 可选的父节点ID,表示该节点可能是根节点
children?: CategoryNode[]; // 可选的子节点数组,表示递归结构
}
// 使用递归类型创建一个映射,将类别节点映射为包含子节点的数组
type CategoryMap = {
[id: number]: CategoryNode & { children: CategoryMap };
};
// 示例:创建一个分类树
const categoryTree: CategoryMap = {
1: {
id: 1,
name: "Electronics",
children: {
2: {
id: 2,
name: "Televisions",
children: {
4: {
id: 4,
name: "LED TVs",
children: {}
},
5: {
id: 5,
name: "Plasma TVs",
children: {}
}
}
},
3: {
id: 3,
name: "Cameras",
children: {}
}
}
}
};
// 使用递归类型来定义一个函数,该函数可以获取所有子孙节点的ID
type Ids = CategoryNode['id'];
type DescendantIds<T> = T extends { children: infer C } ? C extends Record<number, CategoryNode> ? Ids | DescendantIds<Values<C>> : never : never;
type Values<T> = T[keyof T];
function getAllDescendantIds(node: CategoryNode): Array<Ids | DescendantIds<CategoryMap>> {
const childrenIds = node.children?.map(getAllDescendantIds) ?? [];
return [node.id, ...childrenIds.flat()];
}
// 使用示例
console.log(getAllDescendantIds(categoryTree[1]));
这段代码定义了一个简单的分类树,并使用了TypeScript的递归类型来获取所有子孙节点的ID。这里使用了递归映射类型(mapped type)和递归条件类型来构建类型结构,以模仿分类树的结构。getAllDescendantIds
函数递归地遍历了整个分类树,收集并返回了所有节点的ID。
评论已关闭