typescripttypescript1.7

How to Iterate Over String Indexed Array In TypeScript?


I have defined a static property as such:

private static colorsByName: { [index: string]: MyColorClass}

but when I attempt to use for... of from the answer listed here: TypeScript for-in statement

for(let value of MyClass.colorsByName) {
    ...
}

I get an error:

Type { [index: string]: MyColorClass; } is not an array type or a string type.

If I switch over to using for in, the error goes away, but value is typed as any.

for(let value of MyClass.colorsByName) {
    ...
}

What is the actual type of value in this case? Ideally I'd like to loop through all values in the colorsByName property, either in a pair approach, or just to get MyColorClass types returned.

for(let value of MyClass.colorsByName) {
    // value: MyColorClass
}

What are my options?


Solution

  • 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.