fmagno
fmagno

Reputation: 1548

Create a class with getters based on the properties of another class

Say I have a class A with a hundred properties:

class A {
  FOO = "foo";
  BAR = "bar";
  // (...) 98 more properties
}

In typescript, how does one go about dynamically defining a class B with one getter for each property of class A?
The corresponding statically defined class B would look like this:

class B {
  get FOO() {
    someFunction('FOO');
  }

  get BAR() {
    someFunction('BAR');
  }

  // (...) 98 more getters
}

The relation between these classes is as follows:

Upvotes: 2

Views: 254

Answers (2)

fmagno
fmagno

Reputation: 1548

This is @georg answer, second suggestion, slightly changed to actually work for me:

class A {
    FOO = "foo";
    BAR = "bar";
    // (...) 98 more properties
}

function someFunction(p, moreStuff) {
    console.log('someFunction', p, moreStuff)
}

class B extends A {
    constructor(private something: Something) {
        super();
        const someth = this.something;
        return new Proxy({} as any, {
            get(target, p) {
                return p in target ? Reflect.get(target, p) : someFunction(p, someth)
            }
        })
    }
}

b = new B()
b.FOO
b.BAR

Upvotes: 1

georg
georg

Reputation: 214959

One option is to define getters on the fly:

class A {
    FOO = "foo";
    BAR = "bar";
    // (...) 98 more properties
}

function someFunction(p) {
    console.log('someFunction', p)
}

class B {
    constructor(a) {
        for (let p of Object.getOwnPropertyNames(a))
            Object.defineProperty(this, p, {
                get: () => someFunction(p) 
            })
    }
}

b = new B(new A)
b.FOO
b.BAR

I guess you need to pass a to someFunc as well, otherwise how would it know from which object to pick the property?

Another is to use a Proxy:

class A {
    FOO = "foo";
    BAR = "bar";
    // (...) 98 more properties
}

function someFunction(p) {
    console.log('someFunction', p)
}

class B {
    constructor() {
        return new Proxy({}, {
            get(target, p) {
                return p in target ? Reflect.get(target, p) : someFunction(p)
            }
        })
    }
}

b = new B()
b.FOO
b.BAR

In the latter case B and A are in fact independent, so that B is just a "hollow" object that redirects everything to someFunc.

Upvotes: 1

Related Questions