如何基于泛型类型“T”初始化TypeORM存储库?

7
我希望能够基于通用类型初始化一个TypeORM仓库。
例如:
import { Connection, Repository } from 'typeorm';

export class GenericService<T> {
    private repository: Repository<T>;

    constructor(connection: Connection) {
        this.repository = connection.getRepository(T);
        // 'T' only refers to a type, but is being used as a value here.ts(2693)
    }

    public async list(): Promise<T[]> {
        return await this.repository.find();
    }

}

但是我无法将泛型类型传递给ORM存储库工厂。

'T'只是一个类型的引用,但在此处被用作值。ts(2693)

我要如何基于泛型类型创建此通用服务?

附:我在C#中确切地做到了这一点,它像魔法一样起作用,节省了我很多时间。


1
你需要明白TypeScript不是C#。TypeScript最终会被转译成JavaScript,所有的泛型、类型等只是为了帮助你确保代码的正确性而存在。一旦被转译,这些东西都会消失,你在生成的JavaScript中看不到它们。所以没有T,因此当然不能将其用作参数。Yeysides提供了一个解决方法。 - Mu-Tsun Tsai
3个回答

6

在Typescript中,您不能将类型用作值,因此您需要使用泛型来检查值的类型:

import { Connection, Repository } from 'typeorm';
    
export class GenericService<T> {
   private repository: Repository<T>;
    
   constructor(connection: Connection, repo: T) {
      this.repository: T = connection.getRepository(repo);
   }
    
   public async list(): Promise<T[]> {
      return await this.repository.find();
   }
    
}

5
通常我会使用EntityTarget类型来避免这个错误。 代码看起来像:
import { Connection, Repository, EntityTarget } from 'typeorm';

export class GenericService<T> {
   private repository: Repository<T>;

   constructor(connection: Connection, repo: EntityTarget<T>) {
      this.repository = connection.getRepository<T>(repo);
   }

   public async list(): Promise<T[]> {
      return await this.repository.find();
   }

}

这是当前 TypeORM 版本上最佳的解决方案。 - ArlanG

1

2023年更新

(typeorm ^0.3.17, typescript 5.1.3)

根据typeorm存储库中发布的几个问题(51529331),几乎所有以前的解决方案或其部分已被弃用(例如,Connection),甚至由于类型演变而不再起作用。

另一种方法是将Entity本身作为泛型<T>传递:

export class GenericService<T extends EntityTarget<ObjectLiteral>> {
    private entityManager: EntityManager;
    private repository: Repository<ObjectLiteral>;

    constructor(entity: T) {
        this.repository = this.entityManager.getRepository(entity);
    }

    public async list() {
        return await this.repository.find();
    }
}

请注意,使用这个示例中的list()方法返回类型应为Promise<ObjectLiteral[]>,而不是Promise<T[]>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接