0

I am novice in Typescript but have more experience with C#. To learn some basics of the Typescript language, I wrote a function that displays the names of properties and their values for an object, a kind of analogue of JSON.stringify method.

export function writeData<T extends object>(data: T): string {
    let result: { key: string, value: any }[] =
        Object.entries(data).map(entry => ({ key: entry[0], value: entry[1] }));
    result.forEach(entry => {
        if (entry.value instanceof Object) {
            entry.value = `{ ${writeData(entry.value)} }`;
        }
    })
    return result.map(d => `${d.key}: ${d.value}`).join(", ");
}

So when I use it with such example

let data = {
    id: 1,
    name: "outer",
    inner: {
        id: 1,
        name: "inner",
    }
}
console.log(writeData(data));
console.log(JSON.stringify(data));

I see the following output which suits me just fine:

id: 1, name: outer, inner: { id: 1, name: inner }        - from writeData    
{"id":1,"name":"outer","inner":{"id":1,"name":"inner"}}  - from JSON.stringify 

But when I use this function with following example I don't get size property of Map object in output. My output is just empty object. I suppose that I should see 'size' property - {"size": 1}. Could you please explain me why I don't have size property of Map object with my own function and also with JSON.stringify?

let data = {
    id: 1,
    name: "outer",
    inner: {
        id: 1,
        name: "inner",
    }
}
// console.log(writeData(data));
// console.log(JSON.stringify(data));

let mapData = new Map<string, any>();
mapData.set("data", data);

console.log(writeData(mapData));
console.log(JSON.stringify(mapData));

1 Answers1

1

Both the Object.entries() method and the JSON.stringify() method only iterate over the own, enumerable properties of objects.

Own properties must exist directly on an object and are not inherited from its prototype chain.

Enumerable properties are those marked with an enumerable flag (see What does enumerable mean?); most normal properties set by obj.prop = val assignments are enumerable, but some are explicitly marked not enumerable to avoid being included when iterating over objects. Accessor properties (such as those implemented as a getter are usually not enumerable.


The size property of a Map is an accessor property of Map.prototype, and therefore, given an instance of Map, the size property is neither own nor enumerable. So it is not included in the results of Object.entries() or JSON.stringify().

jcalz
  • 264,269
  • 27
  • 359
  • 360