TS2693错误:TypeORM抽象类中如何将泛型T作为值传入getRepository?
解决TypeORM中泛型类型无法作为值传入getRepository的问题
问题原因
TypeScript的泛型是编译时类型,编译后会被完全擦除,所以你没法直接把泛型T当作值传给getRepository方法——它在运行时根本不存在,这就是报错TS2693: 'T' only refers to a type, but is being used as a value here的原因。
解决方案
要让抽象类能拿到实体的运行时引用,必须在子类实例化(或抽象类构造)时显式传入实体的构造函数,把它作为类的属性保存,再用来获取Repository。
修改后的抽象Controller类
import { getDataSource } from "../utils/data-source"; import { EntityTarget, ObjectLiteral, Repository } from "typeorm"; export abstract class Controller<T extends ObjectLiteral> { protected repository: Repository<T>; private readonly entityTarget: EntityTarget<T>; // 构造函数接收实体的构造函数作为参数 constructor(entityTarget: EntityTarget<T>) { this.entityTarget = entityTarget; } public init = async () => { // 使用保存的实体构造函数获取Repository this.repository = (await getDataSource()).getRepository(this.entityTarget); }; }
使用示例
比如针对Category实体创建控制器:
import { Controller } from "./Controller"; import { Category } from "../model/category"; export class CategoryController extends Controller<Category> { constructor() { // 传入Category实体的构造函数 super(Category); } // 可以添加自定义业务方法 public async getCategories() { await this.init(); return this.repository.find(); } }
补充说明
- 泛型
T依然用来约束实体类型,保证类型安全; EntityTarget<T>是TypeORM提供的类型,用来表示实体的构造函数或实体元数据引用;- 如果不想在每个子类构造函数里重复传实体,可以进一步封装,但核心逻辑都是要拿到实体的运行时引用。
内容的提问来源于stack exchange,提问作者Janek Nowak
相关产品推荐
相关产品推荐

