Search code examples
typescriptgenericstypeerrorinstantiation

TypeError while instanciating generic Object


I´m getting a TypeError: type is not a constructor while trying to transform API-Data to Frontend-Dtos.

The Transform-Method looks like this:

transform<T>(entities: any[]) {
    const tableDtos = new Array<T>();
    for (const entity of entities) {
      const dto: T = this.factory.createEntity(entity);
      tableDtos.push(dto);
    }
    return tableDtos;
  }

My Factory like this:

export class Factory {
  create<T>(type: (new () => T)): T {
    return new type();
  }
}

I took the solution from here. What am I missing here?

DTO

import { Entity} from 'src/models/api/Entity';

export class EntityTableEntry {

  id: number;
  name: string;

  constructor(entity: Entity) {
    this.id = entity.ID;
    this.name = entity.Name;
  }
}

Entity

export interface Cost {
  ID: number;
  Name: string;
  Description: string;
  Value: number;
}

The reason why I want to have an generic method is, that I would need to re-write the transform method for each API-Call, which is a complete mess!


Solution

  • I am assuming entities contains the data for the objects you want to create. As such it will not be callable with new. You want to pass in the actual class you want to create (maybe assign the data to the new instance):

    class xx {
      factory: Factory = new Factory();
      transform<T>(type: (new () => T), entities: any[]) {
        const tableDtos = new Array<T>();
        for (const entity of entities) {
          const dto: T = this.factory.createEntity(type, entity);
          tableDtos.push(dto);
        }
        return tableDtos;
      }
    }
    
    class Factory {
      createEntity<T>(type: (new () => T), data: any): T {
        var r = new type();
        Object.assign(r, data) // guessing a decent implementation here 
        return r;
      }
    }
    
    class DataClass { a!: number }
    
    var r = new xx().transform(DataClass, [{ a: 1 }]);
    console.log(r);
    
    

    Play