在 TypeScript 中使用解构/扩展复制具有重命名属性的对象

Posted

技术标签:

【中文标题】在 TypeScript 中使用解构/扩展复制具有重命名属性的对象【英文标题】:Using destructuring/spreading to copy object with renamed properties in TypeScript 【发布时间】:2018-08-06 22:39:06 【问题描述】:

我需要一个将对象从一种类型映射到另一种类型的函数:

我有一个这样的对象:

interface IEntityPerson 
  person_id: number
  name: string
  age: number
  address: IAddress


const orig: IEntityPerson = 
  person_id: 1,
  name: 'Ole',
  age: 40,
  address: myAddress

我想使用解构映射到另一种将 person_id 重命名为 personId 的类型:

interface IRenamed 
  personId: number
  name: string
  age: number
  address: IAddress


const newObj: IRenamed = 
  personId: 1,
  name: 'Ole',
  age: 40,
  address: myAddress

我试过了,但没有用:

export function mapContractTemplate(p: IEntityPerson): IRenamed 
  const renamed = 
    person_id: personId,
    ...rest
   = p
  return renamed

我该怎么做?

另外,请注意“地址”属性是一个嵌套对象。有没有一种聪明的方法可以通过解构和/或传播来做到这一点?

【问题讨论】:

【参考方案1】:

解构一个对象已经将解构属性定义为该块范围内的字段,它们不能作为一个组分配给另一个字段。

你可以这样做:

export function mapContractTemplate(p: IEntityPerson): IRenamed 
    const  person_id, address, ...rest  = p;
    return 
        personId: person_id,
        address:  ...address ,
        ...rest
    

这也会创建地址字段的副本,但不会创建它的深层副本。因此,如果address 包含更多嵌套对象或数组,您将不得不手动进行嵌套解构。

【讨论】:

我有一个 JSON 对象,它的键中有各种奇怪的字符(符号、空格等)。我还能以某种方式使用解构吗? 是的,您可能必须使用括号表示法访问属性【参考方案2】:

也许您可以简单地将所有属性复制到新对象并应用如下具体差异:

export function mapContractTemplate(p: IEntityPerson): IRenamed 

  // create a new object and add the new property
  const renamed = 
    personId: p.person_id
  ;

  // blind copy all properties
  for(var key in p) 
     renamed[key]=p[key];
  

  // delete the unwanted 'old' property
  delete renamed.person_id;
  return renamed;

此代码保留相同的地址实例。我不清楚你是否也需要克隆这个对象。

【讨论】:

【参考方案3】:

好吧,据我所知,没有直接的方法来破坏。 你能做的是

export function mapContractTemplate(p: IEntityPerson): IRenamed 
  const clone =  JSON.parse(JSON.stringify(p)) // deep clone the object
  clone.personId = clone.person_id
  delete clone.person_id;
  return clone

【讨论】:

以上是关于在 TypeScript 中使用解构/扩展复制具有重命名属性的对象的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 使用 ES6 解构骚操作

在 TypeScript 中使用解构和休息的类型化函数参数

你可以在 Typescript 函数中有可选的解构参数吗?

如何同时解构和复制数组?

从 TypeScript 中的 useContext 解构值时出错

8TypeScript-解构赋值