Typescript iterate over a Record type and return updated Record

28,334

Something like this...

type Children = ReadonlyArray<string>;

const data: Parent = {
  parent1: ["child1", "child2"],
  parent2: ["child1", "child2"],
};


type MutableObject<T> = { -readonly [P in keyof T]: T[P] };

const updateChildren = (child: Children): Children => {
  return child.map(value => value + 'updated');
}

let newObj: Parent = Object.entries(data).reduce<MutableObject<Parent>>((acc, cur) => {
  acc[cur[0]] = updateChildren(cur[1]);
  return acc;
}, {})

console.log(newObj)

Share:
28,334
Aniks
Author by

Aniks

Updated on July 09, 2022

Comments

  • Aniks
    Aniks almost 2 years

    I am new to Typescript and I need to iterate over a Record type make some updates to the values and return the Record.

    This is how the types are defined:

    type Parent = Readonly<Record<string, Children>>;
    type Children = ReadonlyArray<string>;
    

    Here is some sample data I would like to iterate over:

    const data = {
        parent1: ["child1", "child2"],
        parent2: ["child1","child2"]
    };
    

    Method to update values in record:

    const updateChildren = (child: Children) : Children => {
        return child.map( value => value + 'updated');
    }
    

    I am struggling to write the syntax for it, tried to look for examples but couldn't find anything helpful.

    I am able to iterate over the record using Object.entries

    Object.entries(data).forEach(([key, value]) => console.log(key, value));
    

    I also tried to use Object.keys

    Object.keys(data)
                .map(key => updateChildren(data[key]))
    

    I guess I am close but not sure how to return the map as here its returning Array [Array]

    Is there some nice way to iterate do the update and it would return the updated data in same type used.

    Thanks for reading.

    Here is the javascript snippet of what I am trying to do and get the updatedMap in example below.

    const data = {
        parent1: ["child1", "child2"],
        parent2: ["child1","child2"]
    };
    
    function updateChildren(children) {
      return children.map(child => child+'updated');
    }
    
    const updatedMap = new Map();
    
    for (const [key, value] of Object.entries(data)) {
      updatedMap.set(key, updateChildren(value));
    }
    
    updatedMap.forEach((value, key) => console.log(key + ":" + value));
    
    
    console.log(Object.keys(data).map(key => updateChildren(data[key])));

  • Aniks
    Aniks almost 4 years
    I am trying to write something like this but for the Parent type instead of map in this snippet Object.keys(data).reduce((map, currentItem) => { const updated = updateChildren(data[currentItem]); return map.set(currentItem, updated) }, new Map()); so if I can pass {} instead trying to come up with syntax for that.
  • risingBirdSong
    risingBirdSong almost 4 years
    Here is using reduce with {} rather than Map repl.it/@risingBirdSong/GleefulDeepskyblueDatabase#index.ts
  • risingBirdSong
    risingBirdSong almost 4 years
    Not implemented but here's how you could type the Map let mapTest = new Map<string, MutableObject<Children>>();
  • Aniks
    Aniks almost 4 years
    I have accepted the answer, you can update it to reflect the change in repl