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.