升级TypeORM至0.3.7遇类型错误:如何按moment.Moment类型排序?
问题
将TypeORM从0.2.45版本升级到0.3.7版本后,以下查询代码中的createdAt字段出现类型错误(升级前可正常运行):
const userTotalEvent = await EventRepository.find({ where: { user: { id: user.id }, type, invitationId }, order: { createdAt: 'DESC' } });
错误提示:
Type 'string' is not assignable to type 'FindOptionsOrder
'.
相关实体及基类定义如下:
Event实体:
@Entity('event') export default class Event extends BaseEntity { @PrimaryGeneratedColumn() public id!: number; @ManyToOne(() => User, (user: User) => user.event) public user!: User; @Column({ type: 'int' }) public verificationAttempts!: number; }
BaseEntity基类:
export default class BaseEntity { @Column({ type: 'datetime', transformer: datetimeSerializer() }) @Transform(momentToString()) public readonly createdAt: moment.Moment; @Column({ type: 'datetime', transformer: datetimeSerializer() }) @Transform(momentToString()) public updatedAt: moment.Moment; constructor() { super(); this.createdAt = moment(); this.updatedAt = moment(); } }
解决方案
方法1:显式指定排序值类型
给createdAt的排序值指定FindOptionsOrderValue类型,绕过TypeScript的类型校验:
import { FindOptionsOrderValue } from "typeorm"; const userTotalEvent = await EventRepository.find({ where: { user: { id: user.id }, type, invitationId }, order: { createdAt: 'DESC' as FindOptionsOrderValue } });
方法2:用类型定义约束查询选项
将查询选项变量声明为FindManyOptions<Event>类型,让TypeORM正确推断排序字段的合法值:
import { FindManyOptions } from "typeorm"; const options: FindManyOptions<Event> = { where: { user: { id: user.id }, type, invitationId }, order: { createdAt: 'DESC' } }; const userTotalEvent = await EventRepository.find(options);
方法3:兼容日期字段的类型声明
修改BaseEntity中日期字段的类型,添加string类型兼容,让排序字符串能被类型系统识别:
export default class BaseEntity { @Column({ type: 'datetime', transformer: datetimeSerializer() }) @Transform(momentToString()) public readonly createdAt: moment.Moment | string; @Column({ type: 'datetime', transformer: datetimeSerializer() }) @Transform(momentToString()) public updatedAt: moment.Moment | string; constructor() { super(); this.createdAt = moment(); this.updatedAt = moment(); } }
方法4:改用QueryBuilder构建查询
使用TypeORM的QueryBuilder替代find方法,类型推断更精准,同时也能灵活控制查询逻辑:
const userTotalEvent = await EventRepository.createQueryBuilder('event') .where('event.userId = :userId', { userId: user.id }) .andWhere('event.type = :type', { type }) .andWhere('event.invitationId = :invitationId', { invitationId }) .orderBy('event.createdAt', 'DESC') .getMany();
内容的提问来源于stack exchange,提问作者Tin Yu
相关产品推荐
相关产品推荐

