在TypeScript类型级别的链表上迭代,不会出现过多的深度错误

在TypeScript类型级别的链表上迭代,不会出现过多的深度错误,typescript,tuples,variadic,type-level-computation,recursive-type,Typescript,Tuples,Variadic,Type Level Computation,Recursive Type,**这是一个有关TypeScript ^4.1的问题** 我有一个递归链表类型 interface ListNode { value: string; next: ListNode | undefined; } 下面是一个类型级实例的示例 type RootNode = { value: "a"; next: { value: "b"; next: { value: "c"; n

**这是一个有关TypeScript ^4.1的问题**

我有一个递归链表类型

interface ListNode {
  value: string;
  next: ListNode | undefined;
}
下面是一个类型级实例的示例

type RootNode = {
  value: "a";
  next: {
    value: "b";
    next: {
      value: "c";
      next: undefined;
    };
  };
};
我想将这种窄链表类型展平为以下类型

type Flattened = [
  {value: "a"},
  {value: "b"},
  {value: "c"},
]
我一直遇到TS错误2589(深度过大/可能无限大)

以下是我迄今为止采取的两种方法

  • 递归元组扩展
  • 类型展平=[
    省略
    …(T[“下一步”]扩展ListNode
    压平
    : [])
    ]
    
  • 使用映射类型模拟元组
  • 类型展平<
    T扩展ListNode,
    I扩展未定义的[]=[]
    > =
    T[“下一步”]扩展ListNode
    ? 记录并展平
    :记录;
    
    我甚至尝试硬编码增量

    type Increment = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    
    type Flatten<
      T extends ListNode,
      I extends number = 0
    > =
      T["next"] extends ListNode
        ? Record<I, Omit<T, "next">> & Flatten<T["next"], Increment[I]>
        : Record<I, Omit<T, "next">>;
    
    type Increment=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
    类型展平<
    T扩展ListNode,
    I扩展数字=0
    > =
    T[“下一步”]扩展ListNode
    ? 记录并展平
    :记录;
    
    不过,我还是得到了错误2589

    如果有人想出了一个解决办法,我将非常感激听到它是什么


    谢谢。

    结果表明,只有当输入链表类型派生自其他递归类型时,才会发生此错误。上述展平方法按预期工作

    interface ListNode {
      value: string;
      next: ListNode | undefined;
    }
    
    type RootNode = {
      value: "a";
      next: {
        value: "b";
        next: {
          value: "c";
          next: undefined;
        };
      };
    };
    
    type Flatten<T extends ListNode> = [
      Omit<T, "next">,
      ...(T["next"] extends ListNode
        ? Flatten<T["next"]>
        : [])
    ]
    
    type Result = Flatten<RootNode>; // [{value: "a"}, {value: "b"}, {value: "c"}]
    
    接口列表节点{
    值:字符串;
    下一步:ListNode |未定义;
    }
    类型RootNode={
    价值观:“a”;
    下一步:{
    价值:“b”;
    下一步:{
    价值:“c”;
    下一步:未定义;
    };
    };
    };
    类型展平=[
    省略
    …(T[“下一步”]扩展ListNode
    压平
    : [])
    ]
    类型结果=展平;//[{value:“a”},{value:“b”},{value:“c”}]
    
    什么是
    令牌。有
    吗?根据您的回答,您是说这是一个“从其他递归类型派生的链表类型”?@concat对此表示歉意–我错误地忘记将该名称替换为示例的
    ListNode
    。刚刚更新了帖子。哦,那么RootNode之外的什么输入类型导致了你的问题?现在,我认为上述问题可以解决。
    type Increment = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    
    type Flatten<
      T extends ListNode,
      I extends number = 0
    > =
      T["next"] extends ListNode
        ? Record<I, Omit<T, "next">> & Flatten<T["next"], Increment[I]>
        : Record<I, Omit<T, "next">>;
    
    interface ListNode {
      value: string;
      next: ListNode | undefined;
    }
    
    type RootNode = {
      value: "a";
      next: {
        value: "b";
        next: {
          value: "c";
          next: undefined;
        };
      };
    };
    
    type Flatten<T extends ListNode> = [
      Omit<T, "next">,
      ...(T["next"] extends ListNode
        ? Flatten<T["next"]>
        : [])
    ]
    
    type Result = Flatten<RootNode>; // [{value: "a"}, {value: "b"}, {value: "c"}]