在TypeScript中如何动态定义覆盖对象所有路径的联合类型?
TypeScript 任意嵌套对象的属性路径联合类型实现
通用实现代码
你可以通过递归条件类型实现任意层级嵌套对象的属性路径自动推导,无需手动固定层级:
// 通用递归路径类型 type DeepPath<T, Prefix extends string = ''> = { // 遍历当前对象所有可作为键的字符串/数字类型属性 [K in keyof T & (string | number)]: // 如果当前属性值是对象类型,返回两种结果:当前层级路径 + 下一层级拼接后的路径 T[K] extends Record<string | number, any> ? `${Prefix}${K}` | DeepPath<T[K], `${Prefix}${K}.`> // 如果是基础类型值,直接返回当前拼接完成的路径 : `${Prefix}${K}` }[keyof T & (string | number)];
用法示例
针对你给出的data对象,直接传入类型即可得到路径联合类型:
const data = { foo: "foo", bar: "bar", layer1: { foo: "foo", layer2: { foo: "foo", bar: "bar", }, }, }; type Path = DeepPath<typeof data>;
如果你只需要保留到叶子节点的路径,排除layer1、layer1.layer2这类中间对象层级的路径,可调整类型实现如下,最终结果和你给出的预期完全一致:
type DeepLeafPath<T, Prefix extends string = ''> = { [K in keyof T & (string | number)]: T[K] extends Record<string | number, any> ? DeepLeafPath<T[K], `${Prefix}${K}.`> : `${Prefix}${K}` }[keyof T & (string | number)]; type Path = DeepLeafPath<typeof data>; // 输出:"foo" | "bar" | "layer1.foo" | "layer1.layer2.foo" | "layer1.layer2.bar"
内容的提问来源于stack exchange,提问作者Behemoth
相关产品推荐
相关产品推荐

