如何创建具备TypeScript智能提示的递归树形对象构造器
实现带TypeScript智能提示的Cypher树形对象构造器
问题分析
你需要实现一个构造函数,接收嵌套结构的输入,生成同结构的对象,其中叶子节点为路径拼接字符串,同时保留完整的TypeScript智能提示。核心问题是通过递归类型定义让TypeScript推导出生成对象的结构。
解决方案
1. 定义核心类型
首先明确输入结构的类型,再通过递归条件类型推导出生成对象的类型:
// 输入的嵌套结构类型 type Entries = { [key: string]: string | Entries; }; // 递归生成目标树形对象的类型 type TreeFromEntries<T extends Entries> = { [K in keyof T]: T[K] extends string ? string : TreeFromEntries<T[K]>; };
2. 实现构造函数
编写递归构造函数,同时指定返回类型为TreeFromEntries<T>,确保TypeScript能推导出生成对象的结构:
function createCypherTree<T extends Entries>(entries: T, parentPath: string = ''): TreeFromEntries<T> { const result = {} as TreeFromEntries<T>; for (const key in entries) { const currentPath = parentPath ? `${parentPath}.${key}` : key; const value = entries[key]; if (typeof value === 'string') { result[key] = currentPath as TreeFromEntries<T>[typeof key]; } else { result[key] = createCypherTree(value, currentPath) as TreeFromEntries<T>[typeof key]; } } return result; }
3. 验证智能提示
使用时对输入对象添加as const断言,让TypeScript保留精确的键名和结构信息,从而提供完整的智能提示:
// 示例输入 const cypherEntries = { user: { id: 'userId', name: 'userName', posts: { title: 'postTitle', content: 'postContent' } }, comment: 'commentId' } as const; // 生成带智能提示的树形对象 const cypherTree = createCypherTree(cypherEntries); // 此时访问任意节点都会有智能提示,比如: cypherTree.user.id; // 提示类型为string,值为"user.id" cypherTree.user.posts.title; // 提示类型为string,值为"user.posts.title" cypherTree.comment; // 提示类型为string,值为"comment"
关键要点
- 递归条件类型:
TreeFromEntries<T>通过遍历输入类型的每个键,递归推导嵌套结构的类型,确保生成对象的结构与输入完全一致。 as const断言:保留输入对象的字面量类型,让TypeScript能精确推导每个节点的路径和类型。- 类型断言匹配:在构造函数中使用
as TreeFromEntries<T>[typeof key]确保递归返回的类型与目标类型兼容,避免类型报错。
内容的提问来源于stack exchange,提问作者Ronny Efronny
相关产品推荐
相关产品推荐

