From 87521ddd5ef095ebd7e46ccf5a583c850791863b Mon Sep 17 00:00:00 2001 From: PalmDevs Date: Mon, 16 Jun 2025 08:59:33 +0700 Subject: [PATCH] feat(lib/utils/objects): add `defineLazyProperties` --- lib/utils/src/objects.ts | 45 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/utils/src/objects.ts b/lib/utils/src/objects.ts index 190f2eb..f5e109e 100644 --- a/lib/utils/src/objects.ts +++ b/lib/utils/src/objects.ts @@ -105,17 +105,48 @@ export function mergeDeep(target: AnyObject, source: AnyObject) { * @param target The target object to define the property on. * @param property The property key to define. * @param loader The function that will be called to load the property value when accessed. + * @return The target object with the lazy property defined. */ export function defineLazyProperty( target: T, property: K, loader: () => T[K], ) { - Object.defineProperty(target, property, { - configurable: true, - get() { - delete target[property] - return (target[property] = loader()) - }, - }) + return Object.defineProperty( + target, + property, + lazyPropDesc(property, loader), + ) +} + +/** + * Define multiple lazy properties on an object that will be loaded when accessed. + * + * @param target The target object to define the properties on. + * @param loaders An object where each key is a property name and the value is a function that returns the property value when accessed. + * @returns The target object with the lazy properties defined. + */ +export function defineLazyProperties( + target: T, + loaders: Partial T[keyof T]>>, +) { + const descs: PropertyDescriptorMap = {} + + for (const key in loaders) + descs[key] = lazyPropDesc(key, loaders[key]!) + + return Object.defineProperties(target, descs) +} + +function lazyPropDesc( + key: K, + loader: () => T[K], +): PropertyDescriptor { + return { + configurable: true, + get(this: T) { + delete this[key] + return (this[key] = loader()) + }, + } }