为何无法修改TypeORM中实体类的构造函数?
TypeORM自定义实体构造函数导致find方法报错的解决办法
问题背景
我是TypeORM和TypeScript新手,之前的实体类定义和使用都正常:
export class Actor extends BaseEntity { @Column() name: string @Column() age: number } // 创建实例并赋值 let actor = new Actor() Object.assign(actor, { name: "John Doe", age: 50 }) await actor.save() // 查询正常 let actors = Actor.find()
为了简化批量赋值的代码,我给Actor类加了带参数的构造函数:
export class Actor extends BaseEntity { constructor(obj){ super() Object.assign(this, obj) } @Column() name: string @Column() age: number } // 带参数创建实例正常 let actor = new Actor({ name: "John Doe", age: 50 }) await actor.save() // 执行find时报错 let actors = Actor.find()
报错信息:
The 'this' context of type 'typeof Actor' is not assignable to method's 'this' of type '(new () => Actor) & typeof BaseEntity'. Type 'typeof Actor' is not assignable to type 'new () => Actor'. Types of construct signatures are incompatible. Type 'new (obj: any) => Actor' is not assignable to type 'new () => Actor'.ts
报错原因
TypeORM的BaseEntity静态方法(比如find)依赖实体类的无参构造函数来实例化查询结果。当你自定义了带参数的构造函数后,TypeScript会覆盖默认的无参构造函数,导致TypeORM无法按预期创建实体实例,触发类型不兼容的报错。
解决方法
方案1:让构造函数支持无参调用
给构造函数参数设置默认值,同时用Partial<Actor>做类型约束,确保既能传参初始化,也保留无参构造能力:
export class Actor extends BaseEntity { constructor(obj?: Partial<Actor>){ super() if (obj) { Object.assign(this, obj) } } @Column() name: string @Column() age: number }
这样两种使用方式都能正常工作:
// 带参数创建实例 let actor = new Actor({ name: "John Doe", age: 50 }) // 查询方法正常执行 let actors = await Actor.find()
方案2:使用TypeORM官方的create方法
TypeORM自带create静态方法,专门用来创建带初始值的实体实例,完全替代new Actor()+Object.assign的写法:
// 创建实例并赋值 let actor = Actor.create({ name: "John Doe", age: 50 }) await actor.save() // 查询不受影响 let actors = await Actor.find()
这是官方推荐的写法,无需自定义构造函数,也不会破坏TypeORM的内部约定。
方案3:新增静态工厂方法
如果不想修改构造函数,可以添加一个静态方法来封装实例创建逻辑:
export class Actor extends BaseEntity { @Column() name: string @Column() age: number static from(obj: Partial<Actor>): Actor { const actor = new Actor() Object.assign(actor, obj) return actor } }
使用方式:
// 通过工厂方法创建实例 let actor = Actor.from({ name: "John Doe", age: 50 }) await actor.save() // 查询方法正常执行 let actors = await Actor.find()
内容的提问来源于stack exchange,提问作者Thomasa13
相关产品推荐
相关产品推荐

