Использование деструктуризации / распространения для копирования объекта с переименованными свойствами в TypeScript

Мне нужна функция, которая отображает объект из одного типа в другой:

У меня есть такой объект:

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
}

Как я могу это сделать?

Также обратите внимание, что свойство address является вложенным объектом. Есть ли умный способ сделать это с помощью деструкции и / или распространения?

3 ответа

Разрушение объекта уже определяет деструктурированные свойства как поля, ограниченные этим блоком, они не могут быть назначены как группа другому полю.

Вы можете сделать это так:

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

Это также создаст копию поля адреса, но не создаст его глубокую копию. Итак, на случай address содержит больше вложенных объектов или массивов, которые вы должны будете выполнить вручную.

Может быть, вы можете просто скопировать все свойства в новый объект и применить определенные различия, как это:

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

Этот код сохраняет тот же экземпляр адреса. Мне было не ясно, нужно ли вам также клонировать этот объект.

Ну, нет никакого способа сделать это с помощью разрушения в моем знании. что вы можете сделать, это

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
}

Другие вопросы по тегам