给定以下对象 struct :
type IObject = { id: string, path: string, children?: IObject[] }
const tree = [
{
id: 'obj1' as const,
path: 'path1' as const,
children: [
{
id: 'obj2' as const,
path: ':pathParam' as const,
children: [
{
id: 'obj3' as const,
path: 'path3' as const
}
]
},
{
id: 'obj4' as const,
path: 'path4' as const,
children: [
{
id: 'obj5' as const,
path: 'path5' as const
}
]
}
]
}
];
我正在try 提取嵌套对象的类型,并将path
个片段累加到该嵌套类型.(假设ID在整个对象中是唯一的)
示例
type ok = FindAndTrackDeepPath<'obj2', typeof tree>['fullPath'];
// type ok = "/path1/:pathParam"
我try 了以下我认为很接近的方法.然而,正如您在第二个(非工作的)示例中所看到的,递归地向下递归该类型时似乎存在一个问题.
export type FindAndTrackDeepPath<
ID,
T extends IObject[],
depth extends number = 1,
path extends string = '',
maxDepth extends number = 10
> = depth extends maxDepth
? never
: FindByID<ID, T> extends never
? FindAndTrackDeepPath<
ID,
Descend<T>['children'],
Increment<depth>,
Descend<T>['path'] extends undefined ? '' : `${path}/${Descend<T>['path']}`
>
: FindByID<ID, T> & { fullPath: `${path}/${FindByID<ID, T>['path']}` };
// helpers
type FindByID<ID, T extends IObject[]> = Extract<T[number], { id: ID }>;
type Descend<T extends IObject[]> = Extract<T[number], { children: IObject[] }>;
type Increment<N extends number> = [1,2,3,4,5,6,7,8,9,10,11,12,...number[]][N];
// examples
type ok = FindAndTrackDeepPath<'obj2', typeof tree>['fullPath'];
// type ok = "/path1/:pathParam"
type notOK = FindAndTrackDeepPath<'obj3', typeof tree>['fullPath'];
// type notOK = "/path1/:pathParam/path3" | "/path1/path4/path3"
type notOK
有两种 Select ,其中一种显然是错误的.
我认为问题在于,当递归下降时,每一层的所有选项的联合是以一种"广度优先"的方式创建的.(例如,发生这样的事情:${("/path 1/:pathParam")|"/path1/path4")}/path3"}) 我已经try 了几种方法来进一步修剪不成功的下降/"unions 的一部分",而下降.但毫无结果.
我找到了几个相关的问题here和here.然而,这些方法提取了所有可能的路径.相反,我只想提取与特定条件(在我的例子中为extends { id: ID}
)匹配的子类型的路径.
有谁能帮帮我吗?这有可能吗?