能否通过N元组格式的对象路径提取TypeScript对象类型?如何实现?
实现基于N元组路径提取对象类型的ExtractType
当然可以实现这个需求!我们可以利用TypeScript的条件类型、递归类型以及元组拆分特性来定义ExtractType,完美匹配你想要的场景。
核心实现代码
type ExtractType<O, T extends PropertyKey[]> = // 拆分元组的第一个元素和剩余部分 T extends [infer First, ...infer Rest extends PropertyKey[]] ? // 检查当前元素是否是对象的有效键 First extends keyof O ? // 递归处理剩余路径,将当前键对应的子类型作为新的对象输入 ExtractType<O[First], Rest> : // 路径中存在无效键时,返回never(可根据需求改为undefined等) never : // 路径元组为空时,返回当前对象的类型(即目标类型) O;
代码逻辑解释
- 元组拆分:通过
T extends [infer First, ...infer Rest extends PropertyKey[]]将路径元组拆分为第一个键First和剩余路径Rest,这是处理可变长度路径的关键。 - 递归遍历:如果
First是当前对象O的有效键,就递归调用ExtractType,把O[First]作为新的对象类型,Rest作为新的路径继续处理。 - 终止条件:当路径元组为空(递归到最后一层)时,直接返回当前的对象类型,也就是我们要提取的目标类型。
- 错误处理:如果路径中出现对象不存在的键,会返回
never,你也可以根据需求修改为undefined或其他自定义类型。
示例验证
我们用你的示例和一些更复杂的场景来验证效果:
// 你的示例场景 type TestObj = { a: { b: number } }; type Foo = ExtractType<TestObj, ['a', 'b']>; // Foo 的类型为 number // 多层嵌套的复杂对象 type NestedUser = { user: { profile: { name: string; age: number; contact: { email: string; phone: string; } } } }; type UserName = ExtractType<NestedUser, ['user', 'profile', 'name']>; // string type UserPhone = ExtractType<NestedUser, ['user', 'profile', 'contact', 'phone']>; // string type InvalidPath = ExtractType<NestedUser, ['user', 'invalidKey']>; // never(无效路径)
额外优化(可选)
如果需要处理对象可能为null或undefined的场景,可以在类型中增加空值判断:
type ExtractType<O, T extends PropertyKey[]> = O extends null | undefined ? never : T extends [infer First, ...infer Rest extends PropertyKey[]] ? First extends keyof O ? ExtractType<O[First], Rest> : never : O;
内容的提问来源于stack exchange,提问作者zimex
相关产品推荐
相关产品推荐

