I am wondering if it is possible to create a type which maps properties of an object to a string where if a certain property value is an object himself, it is added to the string preceded by a dot. Let's say we have an object with the following shape
a: {
b: {
c: 'hello'
}
},
x: {
y: {
z: 'hello'
}
}
The resulting type would be: "a" | "x" | "a.b" | "a.b.c" | "x.y" | "x.y.z"
My attempt in achieving this resulted in the following code
interface A {
a: number
b: {
c: string
d: {
e: {
f: 'hello'
}
}
}
}
type valueof<T> = T[keyof T]
type str<T> = T extends string ? T : never
type record<T> = valueof<{
[K in keyof T]: T[K] extends any[] ? never : T[K] extends Record<string, any> ? K | `${str<K>}.${str<record<T[K]>>}` : K
}>
I think that this is technically correct but it will crash typescript because of the infinite recursion so I will not include a playground link. Did anyone think of any other way of doing it?