1

I two objects with many properties. I want to copy properties from one object to the other only if it's defined.

Here is the object interface:

interface Settings {
  locale: string;
  currency: string;
  style: string;
  isDark: boolean;
  // There are more fields here
}

The two objects are defined like this:

const settings: Settings = {/*assign all fields here*/}
const settingsChange: Partial<Settings> = {/*change some fields*/}

Now I need to assign the fields in settingsChange to settings, I am trying to do this just like I were to do it in javascript

Object.entries(settingsChange).forEach(([key, value])=>{
  settings[key] = settingsChange[key] || settings[key]
})

Here is the typescript linting error I receive:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Settings'.
No index signature with a parameter of type 'string' was found on type 'Settings'.ts(7053)

How do I solve this ? I know that Object.assign would work but Object.entries gives me more freedom to apply whatever logic I need.

just human
  • 51
  • 1
  • 3

1 Answers1

0
settings = {
  ...settings,
  ...settingsChange
};

You can do something like this if you need to do some logic on the values:

settings = Object.fromEntries(Object.entries(settings).map(([key, value]) => {
  const newValue = (settingsChange as keyof Settings)[key] ?? value;
  return [key, newValue];
})) as Settings;
Mike Jerred
  • 9,551
  • 5
  • 22
  • 42
  • This is just like `Object.assign`. I want to use `Object.entries`. It's not a javascript problem. It' a typescript problem. I kind of need to give the right types to make `Object.entries` work – just human Nov 12 '20 at 10:43
  • Thanks for your attempt but this still is not the solution. using `as any` to overcome typescript type checking is never a typescript solution. – just human Nov 12 '20 at 11:02
  • You will need to typecast, take a look at this: https://stackoverflow.com/questions/55012174/why-doesnt-object-keys-return-a-keyof-type-in-typescript If you prefer you could typecast the key to be `keyof Settings` instead of using `any`. I will edit my answer to show this – Mike Jerred Nov 12 '20 at 12:21