Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取TypeScript中递归属性的联合类型_Typescript_Typescript Generics_Mapped Types - Fatal编程技术网

获取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]>