Reputation: 18895
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?
Upvotes: 14
Views: 20706
Reputation: 106790
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
.
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.
Upvotes: 18
Reputation: 4211
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...
}
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...
}
Upvotes: 7