'TypeScript loop trough Object

I have this really easy problem, where I want to loop through an Object in TypeScript.

const an_object = {
    one: 1,
    two: 2,
    three: 3
};

for (let key in an_object) {
    let value = an_object[key];
    // Do something with value
}

This row let value = an_object[key]; is causing a TypeScript error:

[react-scripts] Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ one: number; two: number; three: number; }'.

I'm new to TypeScript and don't really understand the problem.

This works fine on JavaScript but not on TypeScript.

Any suggestions on how to loop through an object in TypeScript correctly, without getting errors?



Solution 1:[1]

For this purpose, I usually write a helper function, so that my "for each object property" loops can be written like follows:

objForEach(an_object, (k, v) => {
    console.log('key', k, 'value', v);
});

The implementation is below. Helpfully, by making it generic, the parameters k and v can have their types inferred correctly depending on an_object:

function objForEach<T>(obj: T, f: (k: keyof T, v: T[keyof T]) => void): void {
    for (let k in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, k)) {
            f(k, obj[k]);
        }
    }
}

Note that I've used hasOwnProperty to check that the property belongs to the object itself rather than another object in its prototype chain (see e.g. this question).

Solution 2:[2]

As @OuuGiii puts it, it's TYPEscript. So just define the key for the loop variable. However, if you are lazy like me and don't wanna define an entire interface notice that you can do something like this:

{ // To make "key" a local variable it must be in a "block" (braces).
// If a block is not used, you cannot use another loop with this iteration
// variable This is especially important if, much like me, you have a bad habit
// of defining "i"s for all the loops.

    let key: keyof typeof an_object;
    for (key in an_object) {
        let value /*: typeof an_object[typeof key] */ = an_object[key];
        // Do something with value
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kaya3
Solution 2 Davoodeh