5

I'm using typeorm and I want to create a generic repository:

import "reflect-metadata";
import { DBManager } from './db-manager';
import { Photo } from './entities/Photo';
import { createConnection, Connection } from "typeorm";

class GenericRepository<T> {
private connection: DBManager;
constructor(connection: DBManager) {
    this.connection = connection;
}

public list(): T[] {
    let result: T[] = [];
    this.connection.connect().then(async  connection => {
        result = await <Promise<T[]>>(connection.entityManager.find(T));
    });
    return result;
 }
}

let genericReposity = new GenericRepository<Photo>(new DBManager());
genericReposity.list();

This code of course doesn't woork and complains on find method that can not find name T

T should be my entity but I don't know how to achieve this

2
  • what doesn't work? what is the actual problem? Commented Nov 26, 2016 at 16:10
  • I edited my example hope it is more clear now but basically .find(T) complains that can not fine name T T should be the Photo but since I want to my class be a generic class so I need somehow to pass the type to my generic method Commented Nov 26, 2016 at 16:48

1 Answer 1

8

Generics in TypeScript are only in compile-type and all information about your generics types are removed in output javascript code. Thats why its not possible to do what you want. Its only possible if you explicitly specify a type to your generic repository, for example via constructor:

import "reflect-metadata";
import { DBManager } from './db-manager';
import { Photo } from './entities/Photo';
import { createConnection, Connection } from "typeorm";

export type ObjectType<T> = { new (): T } | Function;

class GenericRepository<T> {
    private connection: DBManager;
    private type: ObjectType<T>;
    constructor(type: ObjectType<T>, connection: DBManager) {
        this.type = type;        
        this.connection = connection;
}

public list(): T[] {
    let result: T[] = [];
    this.connection.connect().then(async  connection => {
        result = await <Promise<T[]>>(connection.entityManager.find(this.type));
    });
    return result;
 }
}

let genericReposity = new GenericRepository(Photo, new DBManager());
genericReposity.list();

Also side note, you probably don't want to connect to the database each time you request list of entities. So I recommend to redesign your class.

Sign up to request clarification or add additional context in comments.

4 Comments

Tried this solution too but still complains [ts] Argument of type 'T' is not assignable to parameter of type 'ObjectType'. Type 'T' is not assignable to type 'new () => {}'.
For the connection actually i'm using injectors but didn't bring it here
@user4092086 I made small changes, take a look on them. Also take a look on github.com/typeorm/typeorm-typedi-extensions this may help you to organize your code
Thanks this works But I'm wonder how can I bind ObjectType<T> in my injector?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.