如何在TypeScript中让泛型类型支持嵌套对象键?
问题原因
keyof User只能获取User接口的直接属性键,也就是"email"、"password"、"generalInfo"这三个值,而"generalInfo.departmentId"是嵌套层级的属性路径字符串,并不属于keyof User的类型范围,所以TypeScript会抛出类型不匹配的错误。
解决方案
需要定义一个递归泛型类型,用来生成所有嵌套层级的属性路径字符串,替换原来的keyof T类型。
1. 定义嵌套键路径泛型NestedKeyOf
这个泛型会递归遍历对象的所有嵌套属性,生成用点连接的完整路径字符串:
type NestedKeyOf<T> = T extends object ? { [K in keyof T & string]: `${K}` | `${K}.${NestedKeyOf<T[K]>}`; }[keyof T & string] : never;
逻辑说明:如果T是对象类型,就遍历它的每个键K,要么直接返回K,要么把K和子类型T[K]的嵌套路径用点连接起来;如果T不是对象类型,就返回never终止递归。
2. 修改GeneratePipeline类型
将localField的类型从keyof T替换为NestedKeyOf<T>:
type GeneratePipeline<T = any> = { localField: NestedKeyOf<T>; };
3. 验证代码
现在再创建UserPipeLine实例,TypeScript会正确识别嵌套属性路径:
interface User { email: string; password: string; generalInfo: { firstName: string; lastName: string; departmentId: string; }; } const UserPipeLine: GeneratePipeline<User> = { localField: "generalInfo.departmentId" // 不再报错 };
额外说明
如果需要支持数组的索引路径(比如"arrayField.0.id"),可以调整NestedKeyOf的实现,添加对数组类型的处理:
type NestedKeyOf<T> = T extends (infer U)[] ? `${number}.${NestedKeyOf<U>}` : T extends object ? { [K in keyof T & string]: `${K}` | `${K}.${NestedKeyOf<T[K]>}`; }[keyof T & string] : never;
内容的提问来源于stack exchange,提问作者vy.pham
相关产品推荐
相关产品推荐

