0

The two test cases blow both pass. I simply don't understand the behavior. It seems that JavaScript Proxy cannot trap property getting inside a getter function.

test('JS Proxy normal method', () => {
  class Store {
    hidden = false;
    visible() {
      return !this.hidden;
    }
  }
  const accessList: PropertyKey[] = [];
  const proxy = new Proxy<Store>(new Store(), {
    get: (target: any, propertyKey: PropertyKey) => {
      accessList.push(propertyKey);
      return Reflect.get(target, propertyKey);
    },
  });
  expect(proxy.visible()).toBe(true);
  expect(accessList).toEqual(['visible', 'hidden']);
});

test('JS Proxy getter method', () => {
  class Store {
    hidden = false;
    get visible() {
      return !this.hidden;
    }
  }
  const accessList: PropertyKey[] = [];
  const proxy = new Proxy<Store>(new Store(), {
    get: (target: any, propertyKey: PropertyKey) => {
      accessList.push(propertyKey);
      return Reflect.get(target, propertyKey);
    },
  });
  expect(proxy.visible).toBe(true);
  expect(accessList).toEqual(['visible']);
});
5
  • Which of the expectations are failing and how? Commented Aug 28, 2021 at 21:44
  • typescriptlang.org/play?#code/… Commented Aug 28, 2021 at 21:50
  • Btw, your get trap is not forwarding the receiver argument to Reflect.get Commented Aug 28, 2021 at 21:53
  • @Bergi I expect the two to have identical behavior regarding get trap. Thanks for your comment. You may post an answer instead. Commented Aug 28, 2021 at 22:27
  • "Btw, your get trap is not forwarding the receiver argument to Reflect.get" that is the root cause! Please post an answer and I will accept. Thank you very much! Commented Aug 28, 2021 at 22:30

1 Answer 1

2

You're missing the receiver of the property access. The property might be defined on a different object than it is accessed on, and your Reflect.get call needs to take that into account. In particular, the receiver you get as a argument of the get trap is the proxy itself, and that's also the object you want to evaluate the getter against, so that its this value refers to the proxy. However, Reflect.get(target, propertyKey) is the same as target[propertyKey], where the this value in the getter is set to the target and the .hidden property access can't be detected by your proxy.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.