Typescript - slå ihop överlappande egenskaper hos objekt med olika gränssnitt


det kan vara en dum fråga men jag har lite problem med följande gränssnitt. Jag har två objekt:

interface Apple {
  color: 'red' | 'green'
}

interface Orange {
  variety: 'normal' | 'blood'
}

interface Banana {
  plantain: boolean
}


interface A {
  bananas: Banana[],
  oranges: Orange[],
  apples: Apple[],
  lookAtBanana: (banana: Banana) => Banana,
}

interface B {
  bananas: Banana[],
  apples: Apple[]
}

const mergeObjectsOption1 = (state: A, response: B)  => {
  for (const key in response) {
    state[key] = response[key] // Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'B'.
  }
}

const mergeObjectsOption2 = (state: A, response: B)  => {
  for (const key in response) {
    const typedKey = key as keyof typeof response
    const value = response[typedKey];
    state[typedKey] = value; // this is as close as I get to the desired output,but still doesn't work
  }
}
}

Så, vad är det bästa sättet att göra en sådan enkel operation samtidigt som typer behålls genom hela i Typescript? Jag antar att en operator som extraherar en enskild typ från en union baserat på en variabel skulle hjälpa, men kan inte hitta någon :/

Som en ytterligare notering är typ A faktiskt ett this-kontext för en VueJS-komponent.

Lekplats här: https://stackblitz.com/edit/typescript-3xbbzd?file=index.ts

Svar #1

Jag kommer att använda spridningsoperatorn för att förenkla din operation.

interface A {
...
}

interface B {
...
}

const mergeObjects = (a: A, b: B): (A & B) => {
    return {...a, ...b };
}

Obs: Objekten slås samman ytligt här. Om båda objekten dessutom har vissa gemensamma egenskaper kommer det senare objektet (detta är b här) att åsidosätta det första objektets egenskaper.