Proxies allow us to wrap existing object and modify the behavior when interacting with them in some interesting ways. This post will take a look at a few things we can use them for
Something to work with
For the sake of this example we’ll be using Typescript. Let’s create a reference object type that we will interact with - we’re going to call this MyApi and it’s defined simply as an object with a few methods on it:
Initial implementation
We can implement a simple object that satisifies this APi as below:
Log accesses
For this example we’ll consider the illegal method as special. We’ll want to track each time the illegal property is accessed. Using a Proxy we can wrap the baseApi and provide a get method that will handle property access and allow us to see what property of our object is being accessed
When illegal is accessed, we log out a message:
Prevent illegal access
We can also do stuff like create a type of WithoutIllegal version of MyApi in which we remove the property from the type definition. Additionally, we can also make this throw an error if someone attempts to access it at runtime as can be seen below. This is very similar to the previous example but now we have a direct impact on the consumer
Interact with other objects
During the proxying process, we can also do things like interact with objects that aren’t defined within our base object itself:
Creating fake objects
We can also create an object in which any properties can exist and have a specific value, for example an object that has this structure for any key given:
This can be done like so:
It’s also interesting to note that the fake object has no direct properties, and we cxan see that when we log it
Recursive proxies
Proxies can also return other proxies. This allows us to proxy objects recursively. For example, given the following object:
We can create a proxy that tracks different actions, such as property acccess. Recursive proxies can be created by returning a new proxy at the levels that we care about. In the below example, we create a proxy for every property that we access as well as for the result of every function call: