Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript - Update object properties dynamically with Object.entries

I want to implement a function that loops over the properties of an object and applies updates to another object of the same type.

interface Car {
  tires: number;
  name: string;
}

function updateCar(car: Car, updates: Partial<Car>) {
  Object.entries(updates).forEach(([key, value]) => {
    car[key] = value;
  })
}

The issue here is that there is an error

No index signature with a parameter of type 'string' was found on type 'Car'

when casting the key to keyof Car it works, but as soon as using "noImplicitAny": true there is again an error

Type 'string | number' is not assignable to type 'never'

Is there a way to solve this issue in a type-safe matter. Casting the car to any would work but I'd like to avoid it.

Many thanks Bene

like image 904
Bene Avatar asked Aug 25 '20 09:08

Bene


People also ask

How do you dynamically access object property in TypeScript?

To dynamically access an object's property: Use keyof typeof obj as the type of the dynamic key, e.g. type ObjectKey = keyof typeof obj; . Use bracket notation to access the object's property, e.g. obj[myVar] .

How do I add a property to an existing object in TypeScript?

To add a property to an object in TypeScript, set the property as optional on the interface you assign to the object using a question mark. You can then add the property at a later point in time without getting a type error. Copied!

How do you assign values to objects in TypeScript?

assign() method in TypeScript, pass a target object as the first parameter to the method and one or more source objects, e.g. const result = Object. assign({}, obj1, obj2) . The method will copy the properties from the source objects to the target object. Copied!


Video Answer


1 Answers

This question inspired me to revisit a similar problem I ran into.

While not a direct analog of your problem (i.e. this is a pure function that returns a new object rather than modifying arguments supplied by the caller), here's an update function that retains type-safety by using object-spread instead of the Object.entries() function to do its work:

function updateFromPartial<T>(obj: T, updates: Partial<T>):T { 
    return {...obj, ...updates}; 
}
like image 143
spender Avatar answered Sep 21 '22 03:09

spender