2
const expected_keys: String[] = [
    "q",
    "w",
    "e",
    "r",
    "t",
    "y"
];

export function lint(data: any): object {

    var working_keys: String[] = [];
    var linted_data: any = {};

    for (let key in data) {
        console.log(key);                    // Print 1
        if (expected_keys.includes(key)) {
            working_keys.push(key);
        }
    }

    console.log(working_keys);               // Print 2

    for (let key in working_keys) {
        console.log(key);                    // Print 3
        linted_data[working_keys[key]] = data[working_keys[key]];
    }

    return linted_data;
}

On the first print, it looks like the following:

q
w
e
r
t
y

On the second print, it is also qwerty. However, for the third print, i get indexes 0-5 instead of qwerty. Why is this? Both of these arrays have the same type of String[]. Does it have something to do with push()?

Take data to be the following:

{
    "q": "info",
    "w": "info",
    "e": "info",
    "r": "info",
    "t": "info",
    "y": "info",
}

And how come I get the following error but the typescript still compiles and runs as expected?

Type 'String' cannot be used as an index type.

46             linted_data[working_keys[key]] = data[working_keys[key]];
3
  • With regard to the last question, the correct type in TS is string, not String. On mobile so I can't address the main question. Commented Jan 13, 2019 at 1:23
  • What exactly is data? You have it typed as any and haven't included it so this doesn't constitute a minimal reproducible example. But it's obvious that data is some object type, and not an array. And working_keys is an array. The keys of an array are numeric. So you're iterating the keys of different things and they are different; not sure why you expect them to be the same. Commented Jan 13, 2019 at 1:29
  • @jcalz Sorry, edited Commented Jan 13, 2019 at 1:32

3 Answers 3

3

The for...in syntax loops through the properties of an object.

Your third time through is iterating over an array's properties, which are actually the indices of the items in the array.

If you want the value of key to be an item of the array, you should use for...of syntax, or working_keys.forEach instead.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

Sign up to request clarification or add additional context in comments.

Comments

3

First of all: if you access the Array iterator like working_keys the better approach would be to use for .. of loop

Second thing: Try to define the object property with defineProperty constructor like so:

Object.defineProperty(linted_data, key, { value: data });

At last: There might be a problem with typescript type setting under the hood I suppose so you are using String object as a key instead of a pure, basic literal string, perhaps simple casting might solve the problem:

linted_data[working_keys[key].toString()] = data[working_keys[key]];

Comments

1

Print 1 is logging the keys of an object. Print 2 is logging a string[]. Print 3 is logging keys of a string[] (0-5).

If you want Print 3 to log the values of the string array, use for (let key of working_keys). The important difference is the of instead of in.

From the typescript docs:

for..of vs. for..in statements Both for..of and for..in statements iterate over lists; the values iterated on are different though, 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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.