Skip to content

Instantly share code, notes, and snippets.

@nicooga
Created April 9, 2021 18:47
Show Gist options
  • Save nicooga/6f6342d67ca1dc830604fe43a4f53674 to your computer and use it in GitHub Desktop.
Save nicooga/6f6342d67ca1dc830604fe43a4f53674 to your computer and use it in GitHub Desktop.
Use a proxy to inspect properties used in a JS object.
const propertyIsNumeric = (property): boolean => {
if (typeof property === "number") return true;
if (typeof property === "string" && property.match(/\d+/)) return true;
return false;
};
const NON_PROXIED_PROPERTIES = new Set([
"typedAttributes",
"attributes",
"_originalAttributes",
]);
const shouldProxyPropertyValue = (property): boolean =>
!NON_PROXIED_PROPERTIES.has(property);
function propertyUsageInspectionProxy<T = unknown>(
obj: T,
labelPrefix = "",
usedProperties = new Set<string | number | symbol>()
): [T, Set<string | number | symbol>] {
if (obj === null || typeof obj !== "object") {
return [obj, usedProperties];
}
const castedObj = obj as T & object;
const proxy = new Proxy(castedObj, {
get(obj, property): any {
const propertyValue = obj[property];
const propertyDescriptor = propertyIsNumeric(property)
? `[]`
: String(property);
const propertyLabel = `${labelPrefix}.${propertyDescriptor}`;
if (typeof propertyValue !== "function")
usedProperties.add(propertyLabel);
if (!shouldProxyPropertyValue(property)) return propertyValue;
const [potentiallyProxiedPropertyValue] = propertyUsageInspectionProxy(
propertyValue,
propertyLabel,
usedProperties
);
return potentiallyProxiedPropertyValue;
},
});
return [proxy, usedProperties];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment