获取TypeScript中递归属性的联合类型
假设我们有接口:获取TypeScript中递归属性的联合类型,typescript,typescript-generics,mapped-types,Typescript,Typescript Generics,Mapped Types,假设我们有接口: interface Node<C extends Node[] = any[]> { children: C } 现在让我们假设我想要一个类型,它是元组中所有不同类型的并集。我可以做到: type TupleOfNodeChildren<N extends Node> = N['children']; type TypesOfNodeChildren<N extends Node> = TupleOfNodeChildren<
interface Node<C extends Node[] = any[]> {
children: C
}
现在让我们假设我想要一个类型,它是元组中所有不同类型的并集。我可以做到:
type TupleOfNodeChildren<N extends Node> = N['children'];
type TypesOfNodeChildren<N extends Node> = TupleOfNodeChildren<N>[number];
请注意,T22
既有Baz的直接子级Bar,又有Baz的子级Foo
我似乎无法让所有孩子都使用这种类型;不管我怎么做,它总是抱怨循环引用。我假设您需要某种递归来获取所有子类的类型,但我不确定如何在没有TypeScript抱怨的情况下实现它
编辑:
下面是我尝试的一个例子:
type TypesOfAllChildren<N extends Node> = TypesOfNodeChildren<N> | TypesOfAllChildren<TypesOfNodeChildren<N>>;
// ~~~~~~~~~~~~~~~~~~ Recursively references itself
TypesOfAllChildren=TypesOfNodeChildren | TypesOfAllChildren;
//~~~~~~~~~~~~~~~~~~~~~~~递归地引用自身
通过条件类型添加退出条件也不起作用:
type TypesOfAllChildren<N extends Node> = TypesOfNodeChildren<N> | (TypesOfNodeChildren<N> extends never ? never : TypesOfAllChildren<TypesOfNodeChildren<N>>);
TypesOfAllChildren=TypesOfNodeChildren |(TypesOfNodeChildren从不扩展?从不:TypesOfAllChildren);
我解决了它。因此,我们:
interface Node<C extends Node[] = any[]> {
children: C
}
type Foo = Node<[]>
type Bar = Node<[Foo, Foo]>
type Baz = Node<[Bar]>
type Faz = Node<[Baz]>
然后是一切
type T20 = TypesOfAllChildren<Foo> // never
type T21 = TypesOfAllChildren<Bar> // Foo
type T22 = TypesOfAllChildren<Baz> // Bar | Foo <--- Includes types of deep children
type TypesOfAllChildren<N extends Node> = TypesOfNodeChildren<N> | TypesOfAllChildren<TypesOfNodeChildren<N>>;
// ~~~~~~~~~~~~~~~~~~ Recursively references itself
type TypesOfAllChildren<N extends Node> = TypesOfNodeChildren<N> | (TypesOfNodeChildren<N> extends never ? never : TypesOfAllChildren<TypesOfNodeChildren<N>>);
interface Node<C extends Node[] = any[]> {
children: C
}
type Foo = Node<[]>
type Bar = Node<[Foo, Foo]>
type Baz = Node<[Bar]>
type Faz = Node<[Baz]>
type SelfAndAllChildren<N extends Node> = N['children'][number] extends never ? N : {
// @ts-ignore
getSelfAndChildren: N | SelfAndAllChildren<N['children'][number]>
}[N extends never ? never : 'getSelfAndChildren']
type JustAllChildren<N extends Node> = SelfAndAllChildren<N['children'][number]>