2
class a {

    public COUNTS = new Set<string>();

    constructor() {
    }

    public execute(): any {

        this.COUNTS.add('a');
        this.COUNTS.add('b');

        console.log(this.COUNTS);

        return { contas: this.COUNTS };
    }

}

const x = (new a()).execute();

console.log(x);
  

The first console log return the set created as expected, but the second one just return { contas: {} }. I wanna know why this only happens whith SET and MAP.

Robin Zigmond
  • 17,805
  • 2
  • 23
  • 34
  • 2
    I can't precisely replicate this: if I run it in the TS playground I see what you say you get, but if I actually run the code in chrome I get the expected output instead. If you only ever saw that in the TS playground it's an artifact of that environment, but if you see that in a browser or node.js please give us which one and the version. – Jared Smith Jul 26 '23 at 18:16
  • 1
    I think it might be a quirk of how different console implementations display Sets when logged directly - like @JaredSmith I saw the results you indicated in the TS playground, but when putting it into a snippet here (stripping off the TS parts so it's valid JS), it showed me an empty object for *both* logs. Does it work better if you log `[...x]`? [This question](https://stackoverflow.com/questions/45571101/how-can-i-display-a-javascript-es6-map-object-to-console) (about maps rather than sets but you say your issue applies to those too) may possibly be relevant (although I'm not certain). – Robin Zigmond Jul 26 '23 at 18:19
  • 1
    Also probably worth noting here that a good bit of the console API is implementation-dependent and IIRC not strictly specified by the standard. – Jared Smith Jul 26 '23 at 18:20
  • I just tried it myself (and realised that of course `[...x]` is an error, you need to spread the `this.COUNTS` inside the returned object) - and indeed that gives the expected result, [try running this example](https://www.typescriptlang.org/play?#code/MYGwhgzhAEbQ3gKEdV0AOBXARiAlsNAMIDyAqgHIAqAytALzQB2ApgO7Q0sAuAPBNwBOeJgHMAfAAoAlAG5kaaMAD2TAYMzBuywTIQo0AXwVosuAtBYAPFsEzcWMgFywmAT30HFqbgAs8EAB0pJS0gWAAJhGSAORgMXJe3n4BweTUNOFRsdgJ8kmKKmrKICyBIMqikilBIRmJBWiCPJiCTAhKqtyQLgDagQM1aaE0ALrQhvKKxogzRQLQVgzQkqwcYDLSgda29o4N8yVlFVVWckA). So it's 100% a console issue. – Robin Zigmond Jul 26 '23 at 18:21

1 Answers1

3

There's nothing wrong here. What you're seeing is how the tool you're using has decided to represent its output.

In the TS Playground, you see this:

enter image description here

But if you take the compiled JavaScript code from there and put it here in StackOverflow's snippet, you see this:

enter image description here

class a {
constructor() {
    this.COUNTS = new Set();
}
execute() {
    this.COUNTS.add('a');
    this.COUNTS.add('b');
    console.log(this.COUNTS);
    return { contas: this.COUNTS };
}
}
const x = (new a()).execute();
console.log(x);

But then if you open Chrome dev tools and look at the console output, you see this:

enter image description here

So it appears that different tools represent the Set in different ways in the console output, and some of them change that representation when the Set is inside of a JavaScript object. The Set should continue to work like a Set, regardless.

If you're building this object to send as a JSON string, note that the JSON representation of a Set object is just {}. So you'll probably need to translate it into something serializable like an array, which you can do with the spread operator:

return { contas: [...this.COUNTS] };
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315