求TypeScript类型定义:将多键路径对象转为嵌套对象
实现带分隔符键的对象展开类型定义
我正在升级wj-config的TypeScript代码,其中一个功能是将带分隔符的键字符串展开为嵌套对象,比如键'a.b.c'会展开为{a: {b: {c: <对应值>}}}。
已经实现了单个键的InflateKey类型:
export type InflateKey<TKey extends string, TValue, TSep extends string> = TKey extends `${infer Key}${TSep}${infer Rest}` ? { [K in Key]: InflateKey<Rest, TValue, TSep> } : { [K in TKey]: TValue; };
现在需要处理包含多个此类键的对象,示例如下:
const dic = { 'a.b': 1, 'a.c': 33, 'h.x': true, 'z.y': 'Hi' }; // 期望转换后的结果类型对应: const result = { a: { b: 1, c: 33 }, h: { x: true }, z: { y: 'Hi' } };
最初想把每个键的InflateKey结果交叉,但语法不合法,以下是正确的类型实现方案:
最终实现代码
// 辅助类型:递归合并交叉类型中的嵌套对象 type Merge<T> = T extends object ? { [K in keyof T]: Merge<T[K]> } : T; // 主类型:处理带分隔符键的对象展开,默认分隔符为'.' export type InflateDictionary<TDic extends Record<string, any>, TSep extends string = '.'> = Merge< { [K in keyof TDic]: InflateKey<K & string, TDic[K], TSep> }[keyof TDic] >;
代码逻辑说明
- 遍历生成单键展开类型:通过
{ [K in keyof TDic]: InflateKey<K & string, TDic[K], TSep> },为输入对象的每个键生成对应的嵌套展开类型,得到一个临时的中间类型。 - 交叉合并所有展开结果:
[keyof TDic]会提取中间类型的所有值类型,TypeScript会自动将这些单键展开类型交叉合并——相同层级的属性会被合并到同一个对象中,比如{a: {b:1}}和{a: {c:33}}交叉后会变成{a: {b:1, c:33}}。 - 递归合并嵌套层级:
Merge辅助类型会递归处理交叉后的嵌套对象,确保最终类型的层级结构清晰,避免保留交叉类型的语法痕迹。
测试验证
用示例对象验证类型:
type TestDic = typeof dic; type InflatedResult = InflateDictionary<TestDic>; // InflatedResult的类型为: // { // a: { b: number; c: number; }; // h: { x: boolean; }; // z: { y: string; }; // }
完全符合预期的嵌套对象类型。
内容的提问来源于stack exchange,提问作者José Ramírez
相关产品推荐
相关产品推荐

