Iterate over object's keys and values in TypeScript

Viewed 6848

In plain JavaScript we can iterate over object props and values like so:

const values = Object.keys(obj).map(key => obj[key]);

In TypeScript this syntax is wrong because the TS compiler is displaying the following message:

"Element implicitly has an 'any' type because expression of type 'string' can't be used to index type Object".

Is there an alternative way not using Map<string, T> to do it and get the value of each key? I encountered this problem while building an app using React and TS and I have in my state an object which I need to do something like this:

const stateJSX: HTMLParagraphElement[] = Object.keys(obj).map(key => <p>`${key}: ${obj[key]}`<p>);

I would like to see others approach and ideas :) Thank you.

4 Answers

Use Object.entries to iterate over both the keys and the values:

Object.entries(obj).map(([key, value]) => `${key}: ${value}`)

Use Object.entries

Object.entries(obj).forEach(([key, value]) => console.log(`${key}: ${value}`))

You can easily use it with some help of keyof operator:

const test = <T extends Record<string, unknown>>(obj: T) => {
 return (Object.keys(obj) as Array<keyof T>).map(key => obj[key])
}

You should asure TS, that key variable could be used as index for obj argument

Object.keys()

To use Object.keys(), (as indicated in the original question), you can add a typecast indicating that the object is an indexable type:

for (const key of Object.keys(obj)) {
  console.log(`${key}: ${(obj as {[key: string]: string})[key]}`);
}

Or use a typecast on the key:

for (const key of Object.keys(obj)) {
  console.log(`${key}: ${obj[key as keyof typeof obj]}`);
}

Object.entries()

Object.entries() may be used without map() as follows:

for (const [key, value] of Object.entries(obj)) {
    console.log(`${key}: ${value}`);
}
Related