Skip to content

Instantly share code, notes, and snippets.

@ftabashir
Last active October 31, 2018 12:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ftabashir/72f4830397f1dc0751625dea95e08b7a to your computer and use it in GitHub Desktop.
Save ftabashir/72f4830397f1dc0751625dea95e08b7a to your computer and use it in GitHub Desktop.
safe Object property access, using ES6's Proxy and also make it typed!
/*
Using ES6's Proxy for safe Object property access
This gist is inspired from:
https://gidi.io/2016/02/07/using-es6-s-proxy-for-safe-object-property-access.html
*/
const isObject = (obj: any) => obj && typeof obj === "object";
const hasKey = (obj: any, key: string | number | symbol) => key in obj;
const UndefinedObj: ProxyHandler<{}> = new Proxy(
{},
{ get: () => UndefinedObj }
);
const either = (val: any, fallback: any) =>
val === UndefinedObj ? fallback : val;
type NoNullField<T> = { [P in keyof T]-?: NoNullField<NonNullable<T[P]>> };
function safe<T extends object>(obj: T): NoNullField<T> {
return new Proxy(obj, {
get(target, name) {
if (hasKey(target, name)) {
const value = target[name];
if (isObject(target[name])) {
return safe(target[name]) as NoNullField<typeof value>;
} else {
return value;
}
}
return UndefinedObj;
}
}) as NoNullField<T>;
}
export { safe, either };
// Example:
const x: { a?: { b: number } } = { a: { b: 3 } };
safe(x).a.b; // no compile error that x.a is possibly undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment