Skip to content

Instantly share code, notes, and snippets.

@miguel-leon
Last active November 1, 2024 00:32
Show Gist options
  • Save miguel-leon/de7c1f5ba58caca39600b43ba4070c72 to your computer and use it in GitHub Desktop.
Save miguel-leon/de7c1f5ba58caca39600b43ba4070c72 to your computer and use it in GitHub Desktop.
Path builder for a propety accessor function
interface Accessor<T, U> {
(state: T): U;
}
function property_access(p: string, optionally_chained: boolean): string {
let result = p;
const letter_start = /^[A-Za-z]/.test(p);
if (!letter_start) {
if (!/^\d+$/.test(p)) {
result = `'${ result }'`
}
result = `[${ result }]`;
}
if (letter_start || optionally_chained) {
result = `.${ result }`;
}
if (optionally_chained) {
result = `?${ result }`;
}
return result;
}
function asPath(accessor: Accessor<any, unknown>): string {
let path = '';
let leaf = {} as any;
let optionally_chained: boolean;
accessor(new Proxy(leaf, {
get(tree, p: string, r) {
path += path ? property_access(p, optionally_chained) : p;
try {
accessor(tree);
optionally_chained = true;
} catch (_) {
optionally_chained = false;
}
leaf = leaf[p] = {};
return r;
}
}));
return path;
}
const deep = (state: any) => state?.g.h.i?.j;
const accessor = (state: any) => deep(state.a?.b?.[1]?.c.d['->'].e.f);
const path = asPath(accessor);
console.log(path) // a?.b?.[1]?.c.d['->'].e.f?.g.h.i?.j
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment