skip to Main Content

I have this code:

class Category {
  constructor(
    readonly _title: string,
  ) { }

  get title() {
    return this._title
  }
}

 type Categories = typeof categories

 const categories = {
  get pets() {
    return new class extends Category {
      constructor() {
        super(
          'Pets',
        )
      }

      get dishes() {
        return new Category(
          'Pets dishes',
        )
      }
    }
  },
  get cloth() {
    return new class extends Category {
      constructor() {
        super(
          'Cloth',
        )
      }

      get accessories() {
        return new Category(
          'Accessories',
        )
      }
    }
  },
}

Object.entries(categories).forEach(([, category]) => {
  // Actual logs:
  // ["_title"]
  // ["_title"]
  // Expected logs: 
  // ["dishes"]
  // ["accessories"]
  console.log(Reflect.ownKeys(category))
})

Why does Reflect.ownKeys return something different from what I expect?
How to get a list of getters?

2

Answers


  1. dishes and accessories are not own properties. They are properties defined on the prototype of the anonymous classes. On the other hand, _title is a own property of the created objects, as that property was added by the constructor (via the super call, in the constructor of Category).

    If you want to only get dishes and accessories as a result, then iterate the prototypes:

      console.log(Reflect.ownKeys(Object.getPrototypeOf(category))
                         .filter(prop => prop !== 'constructor'));
    
    Login or Signup to reply.
  2. The problem is that the getter methods are not part of the instance itself in TypeScript; they are part of the class prototype.
    Based on that, the Reflect.ownKeys(category) will return the own property keys of the instance, which in this case, is just the _title property. It doesn’t include the getter methods.

    If you want to get a list of getters, you need to iterate over the prototype chain using Object.getOwnPropertyNames and Object.getPrototypeOf. Here’s how you can modify your code to achieve that:

    Object.entries(categories).forEach(([, category]) => {
      console.log(Object.getOwnPropertyNames(category));
    });
    

    In this modification, Object.getOwnPropertyNames(category) is used to get the own property names of each category, including the getter methods. This will output the expected logs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search