I have a function below that reduces an object and assigns the result to an object which key is tied to the key of the function it is named after.

import * as lodash from 'lodash';

export const isPromise = (obj) => !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';

export const series = (obj, handler?) => {
    const reducable = lodash.toPairs(obj);
    const v = reducable.reduce((a: any | Promise<any>, [key, fn]) => {
        const addValue = (a, v) => {
            if (isPromise(a) && isPromise(v)) return a.then(a, v.then(v => addValue(a, v)))
            if (isPromise(a)) return a.then(a => addValue(a, v))
            if (isPromise(v)) return v.then(v => addValue(a, v))
            a[key] = v;
            return a;
        }
        if (typeof fn !== 'function') return addValue(a, fn);
        if (isPromise(a)) return a.then(a => addValue(a, fn(a)))
        return addValue(a, fn(a))
    }, {})
    if (!handler) return v;
    if (isPromise(v)) return v.then(handler);
    return handler(v);
}

series({
    a: Promise.resolve('a+'),
    b: ({ a }) => Promise.resolve(`b+ uses a as:${a}`),
    c: Promise.resolve('c+'),
}).then(console.log)

This example works.

However, I would like to add a typescript type check that does not allow a variable not declared higher in the stack to be used.

series({
    a: Promise.resolve('a+'),
    b: ({ a, z }) => Promise.resolve(`b+ uses a as:${a}`),
    c: Promise.resolve('c+'),
}).then(console.log)

This should throw a typescript error because z is not set by any previous key above b.

Is this possible?

0 Answers