【问题标题】:Typescript type utils flat map* (removing a level but keep its sublevel) while preserving object structureTypescript type utils flat map*(删除一个级别但保留其子级别)同时保留对象结构
【发布时间】:2023-01-08 01:23:03
【问题描述】:

例如,如果我有以下类型:

type Before = {
  A: string
  B: {
    C: string
    D: {
      E: number
    }
  }
}

我想通过例如 Remove<Before, "D"> 将其更改为此:

type After = {
  A: string
  B: {
    C: string
    E: number
  }
}

请注意,删除了D,但保留了E

其他值得一提的案例感谢 so_close

情况1

type T = {
 data: {
   data: string;
 }
};

// would be
type T = { };

案例 #2

type T2 = {
  a: {
    b: string;
  };
  b: number;
}

// would be
type T2 = {
  a: { };
}

【问题讨论】:

    标签: typescript typescript-typings typescript-generics


    【解决方案1】:

    猜测你原来的问题是:

    是否可以编写一个泛型类型Remove<T, U>,它的行为与示例中的一样

    然而,一个例子不足以回答这个问题。 考虑以下:

    type T = {
     data: {
       data: string;
     }
    };
    

    使用上面定义的 T,你想要的 Remove<T, "data"> 应该如何表现? 它是否应该删除最深的“数据”字段,导致{ data: {}; }?或者它应该删除最上面的,导致{}

    继续下去:如果我们有以下类型怎么办?

    type T2 = {
      a: {
        b: string;
      };
      b: number;
    }
    

    Remove<T2, "b"> 应该如何表现?它应该导致{a: {}; b: number}还是{a: { b: string; }; }

    我无法发表评论(我的声誉很低),但请解决您问题中提到的歧义。没有它,恐怕只是没有足够的数据来回答。

    尝试:添加更多示例,或口头指定所需类型的行为方式。也许,如果您口头指定,结果会发现您已经用文字写下了实现!

    附言如果您真正想要的只是使用 Typescript 内置实用程序类型将 Before 转换为 After,您可以这样做:

    type After = Omit<Before, "B"> & {
      B: Omit<Before["B"], "D"> & {
        E: Before["B"]["D"]["E"];
      };
    };
    

    此构造使用 Omit 来“忘记”在特定字段中定义的内容,但在使用 Omit 之后我们立即指定所需的字段,并且我们这样做直到达到所需的级别。

    不幸的是,它不是很优雅,但事实是:这几乎是 Typescript 必须提供的

    【讨论】:

    • 感谢您的洞察力。我添加了一些案例
    • 谢谢!如果我的帖子有帮助,请考虑对其进行投票。我刚刚开始赢得声誉,所以这对我有很大帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2017-11-21
    • 2014-11-23
    • 1970-01-01
    • 2019-10-13
    • 2017-08-03
    相关资源
    最近更新 更多