当我们需要获取一个嵌套对象中所有可能的路径时,可以使用递归类型 ObjectPath
来表示所有路径。这个类型表示从根节点到叶子节点的路径,其中每个路径是一个数组,包含从根节点开始到叶子节点的所有键。
ObjectPath 的定义
type ObjectPath<T> =
// 如果 T 是一个对象...
T extends object
// ...并且 T 没有任何键(即它是一个空对象)...
? keyof T extends never
// ...则路径为空数组
? []
// ...否则,对于 T 的每个键 K,我们创建一个以 K 开始并继续 T[K] 的 ObjectPath 为路径的数组
: { [K in keyof T]: [K, ...ObjectPath<T[K]>] }[keyof T]
// 如果 T 不是一个对象,则路径为空数组
: [];
这个递归类型的实现非常巧妙。它首先使用条件类型语法,判断传入的类型 T 是否是一个对象,如果是一个对象,就需要继续处理它的键和值。如果 T 是一个空对象(即没有任何键),则返回一个空数组。否则,对于 T 的每个键 K,我们创建一个以 K 开始并继续 T[K] 的 ObjectPath 为路径的数组,并将所有路径组合成一个联合类型。
示例
例如,如果我们有一个如下的嵌套对象:
type ExampleObject = {
a: {
b: {
c: number;
};
d: string[];
};
e: boolean;
};
那么 ExampleObject 的 ObjectPath 类型将是以下联合类型:
type ExampleObjectPath =
| ['a', 'b', 'c']
| ['a', 'd', number]
| ['e']
这个联合类型表示所有可能的路径,其中每个数组表示从根节点到叶子节点的路径,第一个元素是对象的一个键,后面的元素是嵌套对象中的键。
希望这个解释可以更好地理解 ObjectPath 类型的实现。如果您有任何问题,请随时问我。