This post is already covering how to get all paths of leaves of an object. I'm using this
type DotPrefix<T extends string> = T extends '' ? '' : `.${T}`;
/**
* Extracts paths of all terminal properties ("leaves") of an object.
*/
export type PropertyPath<T> = (
T extends object
? {
[K in Exclude<keyof T, symbol>]: `${K}${DotPrefix<PropertyPath<T[K]>>}`;
}[Exclude<keyof T, symbol>]
: ''
) extends infer D
? Extract<D, string>
: never;
which is based on this #66661477 answer. But now I need to pull all those paths up by one level. That is, instead of picking "album.track.id"
in
interface Track {
album: {
track: {
id: string
}
}
}
I need to pick "album.track"
which is the path of the parent of the leaf "album.track.id"
.
How can it be done? If you know the leaves' keys, you can do this:
type ParentPath<
T,
P extends PropertyPath<T>,
K extends string
> = P extends `${infer Head}.${K}` ? Head : never;
(which should be improved by constraining K
to keyof ...
), but what if I don't want to pass the key? The problem is, with setting K
to string
, Head
will be inferred as the string up to the first "."
.