这篇文章已经介绍了如何获取对象的叶子的所有路径。我正在用这个
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;
这是基于这个#66661477答案。但现在我需要将所有这些路径提升一级。也就是说,不要在 中选择
"album.track.id"
interface Track {
album: {
track: {
id: string
}
}
}
我需要选择"album.track"
,这是叶子
"album.track.id"
的父级路径。如何才能做到呢?如果你知道叶子的键,你可以这样做:
type ParentPath<
T,
P extends PropertyPath<T>,
K extends string
> = P extends `${infer Head}.${K}` ? Head : never;
(应该通过将 K
限制为
keyof ...
来改进),但是如果我不想传递密钥怎么办?问题是,将
K
设置为
string
时,
Head
将被推断为一直到first
"."
的字符串。
export type ParentPath<T> = {
[K in Exclude<keyof T, symbol>]: T[K] extends object
? `${K}${DotPrefix<ParentPath<T[K]>>}`
: '';
}[Exclude<keyof T, symbol>] extends infer D
? Extract<D, string>
: never;
就像PropertyPath
一样,只是它忽略了非类对象属性的键...