How to Iterate Over String Indexed Array In TypeScript?

It's not an array—it's an object with string keys and values of type MyColorClass.

What you can do, is turn it into an array by getting an array of the object's keys then mapping the keys to the properties of the object:

const colors = Object.keys(MyClass.colorsByName).map(key => MyClass.colorsByName[key]);

Since you might do this a lot, you could create a reusable function to turn the properties into an array:

function propsToArray<T>(obj: { [index: string]: T; } | { [index: number]: T; }) {
    return Object.keys(obj).map(prop => obj[prop]);
}

Then you use it like so:

for (const color of propsToArray(MyClass.colorsByName)) {
    // use color here
}

Side note: You may just want to store this cached on a static property of MyClass.

Object.values

Alternatively, you could also use Object.values():

for (const color of Object.values(MyClass.colorsByName)) {
    // use color here
}

But you might need to add a polyfill if you use that.


for..in

When looking at the Typescript documentation (Typescript: Iterators and Generators), we see that the for..in syntax will iterate over the keys of the object.

for..in returns a list of keys on the object being iterated, whereas for..of returns a list of values of the numeric properties of the object being iterated.

We can use that to our advantage to index into our object and get the strongly typed value:

// Go through each key of the indexed object:
for (const key in indexedObject)
{
   // Get the indexed item by the key:
   const indexedItem = indexedObject[key];
   // Now we have the item.

   // Use it...
}

Solution

We can use that to get an elegant solution to the question:

// Go through each named color:
for (const colorName in colorsByName)
{
   // Get the strongly typed color with this name:
   const color = colorsByName[colorName]; // : MyColorClass
   // Now we have the the strongly typed color with this name.

   // Paint the world in a techni-colour rainbow...
}