Skip to content

Instantly share code, notes, and snippets.

@jbr
Last active December 4, 2019 20:48
Show Gist options
  • Select an option

  • Save jbr/f13263fcfa37e6efa1ef942a780b7682 to your computer and use it in GitHub Desktop.

Select an option

Save jbr/f13263fcfa37e6efa1ef942a780b7682 to your computer and use it in GitHub Desktop.

Revisions

  1. jbr revised this gist Dec 4, 2019. 1 changed file with 20 additions and 0 deletions.
    20 changes: 20 additions & 0 deletions promiseProxy.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    function existingFunction(promise, property) {
    return (...args) => buildProxy(promise[property].apply(promise, args));
    }
    function buildProxy(promiseOrValue) {
    const promise = "then" in promiseOrValue ? promiseOrValue : Promise.resolve(promiseOrValue);
    return new Proxy(promise, {
    get(target, property) {
    if (property in promise)
    return existingFunction(promise, property);
    return (...args) => buildProxy(new Promise(resolve => target.then(m => {
    const method = m[property];
    const results = method.apply(m, args);
    resolve(results);
    })));
    }
    });
    }
    exports.default = buildProxy;
  2. jbr created this gist Dec 4, 2019.
    49 changes: 49 additions & 0 deletions promiseProxy.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    type ProxiedDynamic<T> = {
    [K in FunctionKeys<T>]: (
    ...args: Parameters<T[K]>
    ) => Proxied<ReturnType<T[K]>>;
    };

    type Proxied<T> = ProxiedDynamic<T> & Promise<T>;

    type FunctionKeys<T> = {
    [K in keyof T & string]: T[K] extends (...args: any[]) => any ? K : never;
    }[keyof T & string];

    function existingFunction<T, U extends keyof Promise<T>>(
    promise: Promise<T>,
    property: U
    ) {
    return (...args: Parameters<Proxied<T>[U]>) =>
    buildProxy(promise[property].apply(promise, args));
    }

    export default function buildProxy<T>(
    promiseOrValue: Promise<T> | T
    ): Proxied<T> {
    const promise =
    "then" in promiseOrValue ? promiseOrValue : Promise.resolve(promiseOrValue);
    return new Proxy(promise, {
    get<V, W extends FunctionKeys<V>>(target: Promise<V>, property: W) {
    if (property in promise)
    return existingFunction(
    promise,
    (property as unknown) as keyof typeof promise
    );

    return (...args: Parameters<V[W]>) =>
    buildProxy(
    new Promise<ReturnType<V[W]>>(resolve =>
    target.then(m => {
    const method = m[property] as (
    ...args: Parameters<V[W]>
    ) => ReturnType<V[W]>;

    const results = method.apply(m, args);
    resolve(results);
    })
    )
    );
    }
    }) as Proxied<T>;
    }