0

Given the object ;

const t = {
        grandmother: {
            mother: {
                child: 'Peter',
            },
        },
    };

Where i want to retrieve value of key child using

getChildKey(t, 'grandmother.mother.child')

Which works find given the following function

    interface NestedObject {
        [path: string]: NestedObject | string;
    }

    const getChildKey = (objectStructure: NestedObject, keyIdentifier: String) => {
        const [selectedIdentifier, ...childIdentifier] = keyIdentifier.split('.');
        // eslint-disable-next-line no-prototype-builtins
        if (objectStructure.hasOwnProperty(selectedIdentifier) && childIdentifier.length > 0) {
            if (typeof objectStructure[selectedIdentifier] === 'object') {
                return getChildKey(
                    objectStructure[selectedIdentifier] as NestedObject,
                    childIdentifier.join('.')
                );
            }
        } else {
            return objectStructure[selectedIdentifier];
        }
    };

I am only to able to resolve the inconsistent return of the function;

TS7023: 'getChildKey' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.

Anyone a suggestion to make this work for any return type of key child? E.g. value of child could be a string, number or object.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
pcvnes
  • 927
  • 2
  • 15
  • 41
  • This question may be of high relevance to you: https://stackoverflow.com/questions/69126879/typescript-deep-keyof-of-a-nested-object-with-related-type – Alex Wayne Feb 03 '22 at 20:32
  • 1
    I don't _think_ it's impossible to implement your request in a type-safe way, but it's likely not practical. A signature like `getChildKey(t, ['grandmother', 'mother', 'child'])` would probably make it much easier to type if you can refactor it that way. However, all of this seems like quite a bit of ceremony for bracket accessor indexing (e.g. `t['grandmother']['mother']['child']`). Are the dot-infixed accessors some type of user input at runtime? – jsejcksn Feb 03 '22 at 21:53
  • The dot-infixed accessors are a string as a value for an objects key. Sort of config file. – pcvnes Feb 04 '22 at 06:44

1 Answers1

0

Thanks to jsejcksn followed a totally different approach;

const getNestedValue = (
    objectStructure: { [key: string]: any },
    keyIdentifier: Array<string>
) => {
    let returnObj = objectStructure;
    const valueFound = Object.values(keyIdentifier).every((objKey) => {
        if (returnObj[objKey]) {
            returnObj = returnObj[objKey];
            return true;
        }
        return false;
    });

    return valueFound ? returnObj : undefined;
};
pcvnes
  • 927
  • 2
  • 15
  • 41