简体   繁体   English

在没有过多深度错误的情况下迭代 TypeScript 类型级链表

[英]Iterate Over TypeScript Type-level Linked List without Excessive Depth Error

** This is a question relating to TypeScript ^4.1 ** ** 这是一个关于 TypeScript ^4.1 的问题 **

I have a recursive linked-list type.我有一个递归链表类型。

interface ListNode {
  value: string;
  next: ListNode | undefined;
}

Here's an example of a type-level instance.这是一个类型级实例的示例。

type RootNode = {
  value: "a";
  next: {
    value: "b";
    next: {
      value: "c";
      next: undefined;
    };
  };
};

I'd like to flatten this narrow linked list type into the following type.我想将这种窄链表类型展平为以下类型。

type Flattened = [
  {value: "a"},
  {value: "b"},
  {value: "c"},
]

I keep running into TS error 2589 (excessive depth / possibly infinite).我一直遇到 TS 错误 2589(深度过大/可能无限)。

Here are the two approaches I've taken so far.这是我迄今为止采取的两种方法。

  1. Recursive tuple spread.递归元组传播。
type Flatten<T extends ListNode> = [
  Omit<T, "next">,
  ...(T["next"] extends ListNode
    ? Flatten<T["next"]>
    : [])
]
  1. Simulating a tuple with a mapped type.模拟具有映射类型的元组。
type Flatten<
  T extends ListNode,
  I extends undefined[] = []
> =
  T["next"] extends ListNode
    ? Record<I["length"], Omit<T, "next">> & Flatten<T["next"], [...I, undefined]>
    : Record<I["length"], Omit<T, "next">>;

I even tried hardcoding the incrementation.我什至尝试硬编码增量。

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">>;

Still, I get error 2589.尽管如此,我还是收到了错误 2589。

If anyone has devised a workaround, I'd be extremely grateful to hear what it is.如果有人设计了一种解决方法,我将非常感激听到它是什么。

Thank you.谢谢你。

Turns out this error only occurs when the input linked-list type is derived from other recursive types.原来只有当输入链表类型是从其他递归类型派生时才会发生此错误。 The above flatten methods work as expected.上述展平方法按预期工作。

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"}]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM