如何用TypeScript从字符串数组构建Mikro-ORM的FindOptions.orderBy?
如何用字符串数组动态构建Mikro-ORM的FindOptions排序规则?
问题描述
我正在使用Mikro-ORM,需要实现一个通用函数,从字段名数组动态构建FindOptions<T>中的orderBy配置,而非硬编码字段名。
已知FindOptions接口定义如下:
export interface FindOptions<T, P extends string = never> { populate?: readonly AutoPath<T, P>[] | boolean; orderBy?: (QueryOrderMap<T> & { 0?: never; }) | QueryOrderMap<T>[]; limit?: number; offset?: number; // 其他属性... }
直接硬编码时能正常获得类型提示:
const MikroORMSortBy: FindOptions<TimeEntryEntity> = { orderBy: { EntryDate: QueryOrder.ASC, Id: QueryOrder.ASC, UserId: QueryOrder.ASC } };
但现在需要从字符串数组(比如['EntryDate', 'Id', 'UserId'])动态生成orderBy对象,不清楚具体实现方式。
解决方案
1. 基础实现(forEach循环)
初始化空对象后,通过遍历字段数组逐个添加排序规则:
import { QueryOrder, FindOptions } from '@mikro-orm/core'; import { TimeEntryEntity } from './entities/TimeEntryEntity'; const fields: string[] = ['EntryDate', 'Id', 'UserId']; const orderBy: Record<string, QueryOrder> = {}; fields.forEach(field => { orderBy[field] = QueryOrder.ASC; }); const findOptions: FindOptions<TimeEntryEntity> = { orderBy };
2. 简洁的reduce实现
利用数组reduce方法一行完成对象构建:
const fields: string[] = ['EntryDate', 'Id', 'UserId']; const orderBy = fields.reduce((acc, field) => { acc[field] = QueryOrder.ASC; return acc; }, {} as Record<string, QueryOrder>); const findOptions: FindOptions<TimeEntryEntity> = { orderBy };
3. 类型安全的通用函数
如果需要确保字段数组是实体的有效属性名,可以编写泛型函数,借助TypeScript类型约束避免无效字段:
import { QueryOrder, FindOptions, QueryOrderMap } from '@mikro-orm/core'; function buildOrderBy<T>(fields: Array<Extract<keyof T, string>>, order: QueryOrder = QueryOrder.ASC): QueryOrderMap<T> { return fields.reduce((acc, field) => { acc[field] = order; return acc; }, {} as QueryOrderMap<T>); } // 使用示例 const fields: Array<keyof TimeEntryEntity> = ['EntryDate', 'Id', 'UserId']; const orderBy = buildOrderBy<TimeEntryEntity>(fields, QueryOrder.ASC); const findOptions: FindOptions<TimeEntryEntity> = { orderBy };
该函数会强制传入的字段必须是目标实体的有效属性名,保留完整的代码补全和类型检查能力。
补充说明
- 直接用字符串数组构建时,TypeScript可能因类型不匹配报错,可通过
as Record<string, QueryOrder>或as QueryOrderMap<T>进行类型断言。 - 泛型函数的实现方式能最大化保留Mikro-ORM的类型提示优势,避免传入错误字段名。
内容的提问来源于stack exchange,提问作者Steven Scott
相关产品推荐
相关产品推荐

