Sunday, 4 April 2021

How to properly type a dynamic recursive function that merges multiple objects together?

I'm trying to type the below function, which works as expected, but is not typed correctly. I'd like it to autosuggest available values for me as I type them.

I'm relatively new to Typescript, but I haven't been able to figure it out. Here's what I have:

const endpointsA = (base: string) => ({
    GET: {
        FEATURE_A: {
            SOME_PATH: `${base}/featureA`,
        },
    },
});

const endpointsB = (base: string) => ({
    GET: {
        FEATURE_B: {
            SOME_PATH: `${base}/featureB`,
        },
    },
    POST: {
        FEATURE_B: {
            SOME_PATH: `${base}/featureB`,
        },
    },
});

type TMergeEndpoints = {
    [key: string]: Record<string, unknown>;
}[];
type TRecursiveMerge = {
    obj: {
        [key: string]: Record<string, unknown>;
    };
    entries: Array<[string, Record<string, unknown>]>;
};
const mergeEndpoints = (endpoints: TMergeEndpoints) => {
    const result = {};

    const recursiveMerge = ({ obj, entries }: TRecursiveMerge) => {
        for (const [key, value] of entries) {
            if (typeof value === 'object') {
                obj[key] = obj[key] ? { ...obj[key] } : {};
                recursiveMerge({
                    obj: obj[key] as TRecursiveMerge['obj'],
                    entries: Object.entries(value) as TRecursiveMerge['entries'],
                });
            } else {
                obj[key] = value;
            }
        }

        return obj;
    };

    endpoints.forEach((endpoint) => {
        recursiveMerge({ obj: result, entries: Object.entries(endpoint) });
    });

    return result;
};

const base = '/api';

const endpoints = mergeEndpoints([
    endpointsA(base),
    endpointsB(base),
]);

console.log('endpoints', endpoints);

This correctly merges my object, however I get no type suggestion. I've tried playing around with <T>, placing it here and there, but that didn't work out too well. What can I do here?

Typescript playground



from How to properly type a dynamic recursive function that merges multiple objects together?

No comments:

Post a Comment