如何在TypeScript中提取类型的所有字符串属性(含嵌套路径)
提取嵌套对象中符合类型条件的属性路径
假设我们有如下类型:
type Foo = { a : number b : string c : number d : string }
我们希望构造一个类型,比如type Bar = AllStringAttributes<Foo>,让它返回如下新类型:
type Bar = { b : string d : string }
这种场景可以通过以下类型实现:
type KeysOfValue<T, TCondition> = { [K in keyof T]: T[K] extends TCondition ? K : never; }[keyof T]; type Bar = KeysOfValue<Foo, string>;
但这个方法不适用于嵌套对象。比如对于如下类型:
type Bazz = { inner : { a : number, b : string, } }
如何得到等于"inner.b"的类型?
解决方案:递归提取嵌套属性路径
我们可以用递归条件类型遍历嵌套对象的所有层级,收集符合类型条件的属性路径:
// 辅助类型:判断是否为非null的对象类型 type IsObject<T> = T extends object ? T extends null ? false : true : false; // 递归提取符合目标类型的属性路径 type NestedKeysOfValue<T, TCondition> = { [K in keyof T]: // 当前属性值是目标类型,直接返回键名 T[K] extends TCondition ? K : // 当前属性是对象,递归处理并拼接路径 IsObject<T[K]> extends true ? `${K}.${NestedKeysOfValue<T[K], TCondition>}` : never; }[keyof T]; // 测试嵌套类型 type Bazz = { inner : { a : number, b : string, deep: { x: boolean, y: string } }, outer: string } // 结果:"outer" | "inner.b" | "inner.deep.y" type TargetPaths = NestedKeysOfValue<Bazz, string>;
代码说明
IsObject:用来区分原始类型和对象类型,避免对非对象类型进行无效递归。NestedKeysOfValue:- 遍历对象的每个键
K,检查对应值的类型:- 如果值符合目标类型
TCondition,直接返回当前键K; - 如果值是对象类型,就递归处理这个嵌套对象,并用模板字符串把当前键和子路径拼接起来;
- 其他情况返回
never,最终会被联合类型自动过滤。
- 如果值符合目标类型
- 最后通过
[keyof T]提取所有有效路径,形成包含所有层级符合条件的路径联合类型。
- 遍历对象的每个键
这样就能得到所有嵌套层级中值为目标类型的属性路径,比如示例中的Bazz类型会返回"outer" | "inner.b" | "inner.deep.y"。
内容的提问来源于stack exchange,提问作者Derrops
相关产品推荐
相关产品推荐

