ecmascript 6 - Bruke destrukturering/spredning for å kopiere objekt med omdøpte egenskaper i TypeScript


Jeg trenger en funksjon som mapper objekter fra en type til en annen:

Jeg har et objekt som dette:

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

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

Jeg vil bruke destrukturering for å mappe til en annen type hvor person_id blir omdøpt til personId:

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

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

Jeg prøvde dette, men det fungerer ikke:

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

Hvordan kan jeg gjøre dette?

Merk også at 'address'-egenskapen er et nestet objekt. Finnes det en smart måte å gjøre dette på med destrukturering og/eller spredning?

Svar #1

Destrukturering av et objekt definerer allerede de destrukturerte egenskapene som felter med blokkbegrenset omfang, de kan ikke tilordnes som en gruppe til et annet felt.

Du kan gjøre det slik:

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

Dette vil også lage en kopi av adressefeltet, men det vil ikke lage en dyp kopi av det. Så, dersom address inneholder flere nestede objekter eller arrays, må du gjøre den nestede destruktureringen manuelt.

Svar #2

Kanskje du enkelt kan kopiere alle egenskaper til et nytt objekt og bruke de spesifikke forskjellene slik:

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

Denne koden beholder den samme instansen av adresse. Det var ikke klart for meg om du også trengte kloning av dette objektet.

Relaterte artikler