Skip to content

Instantly share code, notes, and snippets.

@mimshins
Created January 7, 2026 14:31
Show Gist options
  • Select an option

  • Save mimshins/f3b3377bc205cc76f1735dc3224bd5ee to your computer and use it in GitHub Desktop.

Select an option

Save mimshins/f3b3377bc205cc76f1735dc3224bd5ee to your computer and use it in GitHub Desktop.
Define a lazily evaluated property on arbitary objects.
type ModifiedObject<
TObject extends Record<string, unknown>,
TPropertyName extends string,
TPropertyValue,
> = TObject & {
[K in TPropertyName]: TPropertyValue;
};
export const defineLazyProperty = <
TObject extends Record<string, unknown>,
TPropertyName extends string,
TPropertyValue,
>(
object: TObject,
propertyName: TPropertyName,
valueGetter: () => TPropertyValue,
): ModifiedObject<TObject, TPropertyName, TPropertyValue> => {
const define = (value: TPropertyValue) =>
Object.defineProperty(object, propertyName, {
value,
enumerable: true,
writable: true,
});
Object.defineProperty(object, propertyName, {
configurable: true,
enumerable: true,
get(): TPropertyValue {
const result = valueGetter();
define(result);
return result;
},
set(value: TPropertyValue) {
define(value);
},
});
return object as ModifiedObject<TObject, TPropertyName, TPropertyValue>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment