2

it might be a silly question but I am struggling a bit with the following interfaces. I have two objects:

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

So, what's the best way to do such simple operation while retaining typings throughout in Typescript? I guess am operator that extracts a single type from a union based on a variable would help, but can't find any :/

As an additional note type A is actually a this context for a VueJS component.

Playground here: https://stackblitz.com/edit/typescript-3xbbzd?file=index.ts

Dave
  • 613
  • 2
  • 5
  • 19
  • 1
    You can't iterate over interfaces. – Roberto Zvjerković Mar 06 '20 at 13:15
  • Your first code block shows two interfaces, which only accept a specific value for their properties - should these be your objects or do your interfaces actually have this limitation? – CGundlach Mar 06 '20 at 13:19
  • Does this answer your question? [Typescript: No index signature with a parameter of type 'string' was found on type '{ "A": string; }](https://stackoverflow.com/questions/56568423/typescript-no-index-signature-with-a-parameter-of-type-string-was-found-on-ty) – CGundlach Mar 06 '20 at 13:19
  • @CGundlach, the string literals are for example only, they would be their own interfaces / types – Dave Mar 06 '20 at 13:30
  • Consider changing that, as it makes it a bit hard helping you. Ideally you would provide a minimal, reproducible example e.g. in StackBlitz. I actually had to create a project first to reproduce your error, since above code works fine without setting the `strict` option to `true`. – CGundlach Mar 06 '20 at 13:48
  • @CGundlach fair point here is a better repro example https://stackblitz.com/edit/typescript-3xbbzd?file=index.ts – Dave Mar 06 '20 at 14:03

1 Answers1

0

I'll use the spread operator to simplify your operation.

interface A {
...
}

interface B {
...
}

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

Note: The objects get shallow merged here. Also, if both objects have some common properties then the latter (that's b here) will overide the former's properties.

Shravan Dhar
  • 1,455
  • 10
  • 18
  • Unfortunately being a vue component I need to assign to `this` but it errors with `The left-hand side of an assignment expression must be a variable or a property access`. I could have a method that takes `this` and the response perhaps but there must be a better way :) – Dave Mar 11 '20 at 10:20