Skip to content

Instantly share code, notes, and snippets.

@Caellian
Last active August 26, 2025 15:24
Show Gist options
  • Select an option

  • Save Caellian/32c9821d785fb2088560d7a0021c93a3 to your computer and use it in GitHub Desktop.

Select an option

Save Caellian/32c9821d785fb2088560d7a0021c93a3 to your computer and use it in GitHub Desktop.
JavaScript lazy function returning a type that behaves like the wrapped function return type
export function lazy<T extends object | Function>(constructor: () => T): T {
let target: [T] | null = null;
function initOrReflect(trap: string | symbol) {
return (_ignored: T, ...args: any[]) => {
if (target === null) {
target = [constructor()];
}
if (target[0] == null) {
switch (trap) {
case "get":
return undefined;
case "set":
throw new TypeError("Cannot set property on null");
case "has":
return false;
case "ownKeys":
return [];
case "getOwnPropertyDescriptor":
return undefined;
case "getPrototypeOf":
return null;
case "apply":
case "construct":
throw new TypeError(
"Null target not callable/constructable"
);
default:
throw new TypeError(
`Trap "${String(trap)}" not supported on null`
);
}
}
return (Reflect as any)[trap](target[0] as unknown, ...args);
};
}
function proxiedTraps(...functions: string[]) {
const result: Record<string, any> = {};
for (const trap of functions) {
result[trap] = initOrReflect(trap);
}
return result;
}
return new Proxy<T>(
(() => {}) as unknown as T,
proxiedTraps(
"apply",
"construct",
"defineProperty",
"deleteProperty",
"get",
"getOwnPropertyDescriptor",
"getPrototypeOf",
"has",
"isExtensible",
"ownKeys",
"preventExtensions",
"set",
"setPrototypeOf"
)
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment