寻求替代TypeScript表名转列名大型条件类型的高性能方案
解决方案:用映射类型替代链式条件类型
核心思路
把表名和列名的映射关系定义成接口类型,通过TypeScript的索引访问类型实现表名到列名的快速查找。这种方式性能远优于嵌套三元条件:链式条件是线性匹配,表越多越慢;而索引访问是直接定位,不会触发栈深度问题,编辑器卡顿、CPU占用高的情况会大幅缓解。
重构后的自动生成代码
/** * 自动生成的部分:用映射表替代分散的列类型 */ type TableColumnMap = { 'public.user': 'id' | 'username'; 'public.department': 'id' | 'department_name'; // 几百/几千张表直接在这个对象里追加即可 }; // 自动推导所有表名联合类型,无需手动维护 type AnyTableName = keyof TableColumnMap; // 替换原来的Convert_TableName_to_ColumnName export type Convert_TableName_to_ColumnName<T extends AnyTableName> = TableColumnMap[T];
原有业务函数无需修改
你的业务函数可以完全保持原样,类型推导和约束逻辑和之前完全一致,不需要做任何代码生成或重载:
function define_sql_index<TableNameGeneric extends AnyTableName>(table_name: TableNameGeneric, columns_array: Convert_TableName_to_ColumnName<TableNameGeneric>[]) {} define_sql_index('public.user', ['username']); // 正常工作,类型提示正确 function pick_some_columns_using_required_bools<TableNameGeneric extends AnyTableName>(table_name: TableNameGeneric, bools_record: Record<Convert_TableName_to_ColumnName<TableNameGeneric>, boolean>) {} pick_some_columns_using_required_bools('public.department', { id: false, department_name: true, }); // 正常工作,类型校验通过
方案优势说明
- 性能提升:链式三元条件每次泛型实例化都要从第一个分支开始逐个匹配,几百张表就意味着几百次条件判断;而映射类型的索引访问是TypeScript内部优化的哈希查找,时间复杂度为O(1),不管表数量多少,查找速度都一致。
- 避免栈溢出:嵌套三元的层级过深会触发TS2321栈深度错误,映射类型不存在这个问题,因为它不是递归或链式判断结构。
- 维护简化:自动生成代码时只需要维护一个
TableColumnMap对象,无需同时维护分散的ColumnsForXXX类型和AnyTableName联合类型,减少重复代码。
关于函数重载的疑问
不需要为业务函数生成重载——上面的方案已经通过泛型+索引访问实现了和重载完全一致的类型约束效果,而且不需要修改任何业务函数代码,完美适配你“表名和列名分开传递”的场景。
内容的提问来源于stack exchange,提问作者LaVache
相关产品推荐
相关产品推荐

