Last active
October 31, 2018 12:02
-
-
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!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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