如何用TypeScript实现支持嵌套键的类型安全数组?
TypeScript实现嵌套键的类型安全数组
要实现支持对象嵌套键(如"b.c")且保持类型安全的数组,你可以通过递归映射类型生成所有合法的嵌套路径联合类型,再以此约束数组元素。
实现步骤
定义递归类型生成嵌套键联合类型
编写一个NestedKeyOf类型,递归遍历对象的所有层级,生成用点分隔的合法路径字符串联合类型:type NestedKeyOf<T extends object> = { [K in keyof T & string]: T[K] extends object ? K | `${K}.${NestedKeyOf<T[K]>}` : K }[keyof T & string];这个类型的逻辑是:
- 遍历对象的所有字符串类型键
K - 如果
K对应的属性是对象,则合法路径包括K本身,以及K拼接子对象的嵌套路径(如b和b.c) - 如果属性是原始类型,则仅
K本身是合法路径 - 最后将所有可能的路径合并为联合类型
- 遍历对象的所有字符串类型键
用嵌套键联合类型约束数组
基于你的对象,生成对应的嵌套键联合类型,再定义数组类型:const obj = { a: "a", b: { c: 1, }, }; type ValidNestedKeys = NestedKeyOf<typeof obj>; type Arr = ValidNestedKeys[];
验证类型安全
- 合法的嵌套键会被允许:
const validArr: Arr = ["a", "b", "b.c"]; // 无报错 - 非法的路径(如不存在的键或错误层级)会触发类型检查错误:
const invalidArr: Arr = ["a.x", "b.d"]; // 类型报错,路径不合法
扩展支持数组索引(可选)
如果需要支持对象中嵌套数组的索引路径(如"b.0.c"),可以调整NestedKeyOf类型兼容数组:
type NestedKeyOf<T> = T extends (infer U)[] ? `${number}.${NestedKeyOf<U>}` | number : T extends object ? { [K in keyof T & string]: T[K] extends object | any[] ? K | `${K}.${NestedKeyOf<T[K]>}` : K }[keyof T & string] : never;
内容的提问来源于stack exchange,提问作者MauricioRobayo
相关产品推荐
相关产品推荐

