2

Is it possible to retrieve / update a nested value in a custom Typescript type using a dotted string?

interface IChild {
  childName: string;
}

interface IRoot {
  root: string;
  child: IChild;
}

const O:IRoot = {
  root: "Root name",
  child: {
    childName: "Child Name"
  }
}

console.log(O['child.childname']); // Not allowed

Is there a way of accessing this prop using dotted notation?

Edit: I have put this together to show how I am getting the value using dot notation from a nested type

    type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]];

    type Join<K, P> = K extends string | number ?
        P extends string | number ?
            `${K}${"" extends P ? "" : "."}${P}`
            : never : never;

    type NestedKeyof<T, D extends number = 10> = [D] extends [never] ? never : T extends object ?
        { [K in keyof T]-?: K extends string | number ?
            `${K}` | Join<K, NestedKeyof<T[K], Prev[D]>>
            : never
        }[keyof T] : ""
        
    const state: IRoot = {
        name: "Root",
        child: {
            childname: "Child1",
            grandchild: {
                childname: "Child2"
            }
        }
    } as IRoot;

    const getProperty = <P extends keyof T, T>(o:T, p:P ) => {
        return o[p];
    }

    const getNestedProperty = <P extends NestedKeyof<T,3>, T>(o:T, p:P ): any => {
        const parts = String(p).split(".");
        let temp: any = getProperty(o, parts[0] as keyof T);
        parts.shift();
        parts.map(p=> {
            temp = getProperty(temp, p as keyof typeof temp);
        })
        return temp;
    }
    
    console.log(getNestedProperty(state, "child.grandchild.childname"));

The magic seems to be that when you have an anonymous type you can type guard using

keyof typeof anonymoustype

So as you recurse the structure you can use this to satisfy typescript.

1 Answers1

-1

First thing, it won't be allowed. The property name is "childName" and you're accessing it as "childname". ( casing issue )

Second, you can access any property using dot notation in ts. Even your IDE will typehint it for you.

Here, check I have just copy pasted your code on this online Playground for TS and changed the console log to dot notation only.

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJIGEAWwA2ATZAbwChlkFt8A5OAWwgC5kBnMKUAcwG5iBfY4qEixEKVACUA9pLBFSyKNLBNW7EN3kVceJhkp4e-YgkkhWyAPIMJS5AF45ZRTKYAiKTOQg6EVwBpNfSYSMjItah83LG1kGnpXeX4jEzNJHAgAOhxJDgAKCwzwvEL9OIgASi4gA

Hesan Naveed
  • 199
  • 5