I'm looking for nested object paths: Is something like this possible?
interface IHuman {
    age: number;
    friend: {
        name: string;
    }
}
keyof IHuman; // "age", "friend.name"
                type AnyObject = Record<string, any>
type DotJoin<A extends string, B extends string> = A extends '' ? B : `${A}.${B}`
type DeepKeys<O extends AnyObject> = {
  [K in keyof O]: O[K] extends AnyObject ? K : never
}[keyof O]
// @ts-expect-error Type 'keyof O' does not satisfy the constraint 'string'.
type DotBranch<O extends AnyObject, P extends string = '', K extends string = keyof O> =
  K extends DeepKeys<O>
  ? DotBranch<O[K], DotJoin<P, K>>
  : /*************/ DotJoin<P, K>
interface Obj {
  a: {
    x: string
    y: {
      z: string
    }
  }
  b: {
    u: boolean
  }
  c: number
}
type D = DotBranch<Obj> // type D = "c" | "a.x" | "a.y.z" | "b.u"
declare function get(path: DotBranch<Obj>)
get('') // Argument of type '""' is not assignable to parameter of type '"c" | "a.x" | "a.y.z" | "b.u"'.
Typescript Playground
GitHub Gist
I don't think this is possible, as for why i can make a wild guess:
interface IHuman {
    age: number;
    'friend.name': any;
    friend: {
        name: string;
    }
}
const b: keyof IHuman = 'friend.name';
friend.name would now be ambigious.
I've not found a nice solution for this too. But you might want to take a look at typed-path project.

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With