Anthony Kong
Anthony Kong

Reputation: 40664

Why some of these code cannot iterate values in a map in typescript?

I am trying out some typescript idioms as described in the answers to this SO question (Iterating over Typescript Map) in Codepen.

Here is my code.

class KeyType {
  style: number;
  constructor(style) {
    this.style = style;  
  };
}

function test() {


  const someMap = new Map<KeyType, number>();
  someMap.set(new KeyType(style=199), 5);
  someMap.set(new KeyType(style=67), 90);

 console.log('test of 1')

  for (let [k, m] of someMap) {
    console.log(`1 k ${k} m ${m}`);
  }

   console.log('test of 2')

  for (let [k, m] of someMap.entries()) {
    console.log(`2 k ${k} m ${m}`);
  }

   console.log('test Object entries')

  for (let [k, m] of Object.entries(someMap)) {
    console.log(`3 k ${k} m ${m}`);
  }

  console.log('for each')

  someMap.forEach((v, id) => console.log(`3 v ${v} id ${id}`))

  Array.from(someMap.entries()).forEach(entry =>
    console.log(`4 k ${entry[0].style} m ${entry[1]}`)
  )

  const ar = Array.from(someMap.keys());
  console.log(ar[0].style);

}

What I do not understand is: all the forEach method work as expected, but the for (let [k,m] of someMap) {... just do not seem to work at all.

Could it be a problem with codepen's typescript configuration? Did I make any mistake with test of 1, test of 2 and test Object entries in the above code?

I wanted to install ts-node to test locally but so far I have gotten another set of issues regarding its installation.

Upvotes: 0

Views: 76

Answers (1)

Karol Majewski
Karol Majewski

Reputation: 25800

First, let's fix the errors you have.

someMap.set(new KeyType(style=199), 5);

This is not valid JavaScript/TypeScript syntax. If you want 199 to be your argument, write it as:

someMap.set(new KeyType(199), 5);

The second thing is how your KeyType class is serialized for the purpose of printing to the console.

  for (let [k, m] of someMap) {
    console.log(`1 k ${k} m ${m}`);
  }

Here, k represents KeyType which in your scope represents a class. JavaScript runtime serializes classes by returning "[object] Object", which I presume is not what you wanted.

If your intention was to log the style of your KeyType, replace it with this:

  for (let [k, m] of someMap) {
    console.log(`1 k ${k.style} m ${m}`);
  }

You can check out the final result in TypeScript Playground.


Note: a common source of confusion is variable overshadowing. Your class is called KeyType, but there is also a global type called the same.

type KeyType = "public" | "private" | "secret";

If your code lives in a file without any import/export statements, it's going to be treated as a script and not a module. It means the global type will take precedence and if you try to call it by new KeyType(), you will receive a compile-time error:

'KeyType' only refers to a type, but is being used as a value here.

Upvotes: 1

Related Questions