Typescript return single or array based on counter value

Viewed 79

I need the create function to return a single model or an array of models based on the count value.


export default abstract class Factory<Model> {
    protected _count: number = 1

    private count(count: number): this {
        this._count = count
        return this
    }

    public create(): Model | Model[] {
        return this.generate()
    }

}

but the problem is that the client code needs to check if the result is an array or not which is not desired.

// data is Model|Model[] but should be Model[]
const date = factory.count(2).create()

// data is Model|Model[] but should be Model
const date = factory.create()

How can I set a condition for create's return type to be an array if the count > 1?

1 Answers

The only way is to make a static initialization of count so that the return type can be specified at compile time.

export class Factory<Model> {

    count(): SingleFactory<Model>;
    count(n: number): ArrayFactory<Model>;
    count(n?: any): any {
      if (arguments.length) {
        return new ArrayFactory<Model>(n);
      }
      return new SingleFactory<Model>();
    }
}

export class SingleFactory<Model> extends Factory<Model> {
    constructor() { super() }
    public create(): Model {
      return {} as Model;
    }
}

export class ArrayFactory<Model> extends Factory<Model> {
    constructor(protected _count?: number) { super() }
    public create(): Model[] {
      return Array(this._count).fill(0).map(x => ({} as Model));
    }
}

const f = new Factory<Model>();
const f1 = f.count().create();
const f2 = f.count(2).create();

It would be easier if you just add count as a parameter to create.

export class Factory<Model> {
    public create(): Model;
    public create(n: number): Model[];
    public create(n?: number): any {
        return arguments.length ? [{}] : {}
    }
}
Related