【问题标题】:How to rename interface keys?如何重命名界面键?
【发布时间】:2020-04-20 13:14:21
【问题描述】:

任务是重命名接口键。嵌套级别可能会有所不同。例如:

interface Foo {
  _id: string
  nested: {
    _id: string
    nested: {
      _id: number
    }
  }
}

// how to create another type that looks like type below?

type Bar = {
  id: string
  nested: {
    id: string,
    nested: {
      id: number
    }
  }
}

因此,在本例中,我想将所有 _id 键重命名为 id,但类型应保持不变。

【问题讨论】:

    标签: typescript types


    【解决方案1】:

    您可以尝试以下类型:

    // T := your object type, K := key to change, R := new key name
    
    type PickRename<T, K extends string, R extends string> =
      T extends object ? K extends keyof T ?
      ({ [P in R]: PickRename<T[K], K, R> } &
        { [P in Exclude<keyof T, K>]: PickRename<T[P], K, R> }) extends infer I ?
      { [PP in keyof I]: I[PP] } : never
      : T
      : T
    

    用你的例子解释

    1. 如果Tobject 并且包含键K ("_id"),则处理该对象,否则我们只返回T

    2. 删除旧属性K (_"id") 并添加重命名的属性R ("id");进一步递归处理每个属性。

    3. extends infer I ? { [PP in keyof I]: I[PP] } : never 部分仅用于 DX/UX/格式化目的,以使相交类型更具可读性。

    /*
    type T1 = {
        id: string;
        nested: {
            id: string;
            nested: {
                id: number;
            };
        };
    }
    */
    type T1 = PickRename<Foo, "_id", "id">
    

    要将其扩展到多个属性,您可以查看可能的 PickRename implementations here

    Playground

    【讨论】:

    • 哇!非常感谢!太棒了!
    • 我正在为此而努力。我喜欢它的简单性,但它不适用于嵌套数组。我尝试在那里填充T extends (infer U)[] ? PickRename&lt;U, K, R&gt;[],但似乎不起作用。任何圣人的智慧都将不胜感激!
    • ^它的工作原理是将倒数第二行替换为: { [P in keyof T]: TransformType2&lt;T[P]&gt; }。干杯。
    • @Piittis 我们偏离了原来的问题,所以简而言之:有一个概念叫做homomorphic mapped types。如果你想保留可选属性或readonly,你最好让它们保持启用状态:
    • PG
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 2016-11-10
    • 1970-01-01
    • 2011-09-05
    相关资源
    最近更新 更多