Last active
August 26, 2025 15:24
-
-
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
This file contains hidden or 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
| 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