kat1330 kat1330 - 3 years ago 156
TypeScript Question

Generic factory based on interface TypeScript

I want to implement generic method which will return concrete type based on provided interface. Is this even possible in TypeScript?

Here is my pseudo example:

interface IDog {
canRun: boolean;
}

interface IBird {
canFly: boolean;
}

class Dog implements IDog {
canRun: boolean;
}

class Bird implements IBird {
canFly: boolean;
}

function createInstance<T>(): T {
const key = typeof T;

switch (key) {
case IBird:
return new Bird();
return
case IDog:
return new Dog();
default:
break;
}
}

// concrete is Dog
const concrete = createInstance<IDog>();


createInstance()
method is a raw example of what I am trying to achieve, it will not compile!

I would like to provide interface type to
createInstance()
method and implement some logic which will create concrete type for provided interface.

Is it possible in TypeScript?

Answer Source

Interfaces are not accessible in runtime, but you can add type checking using String Literal Types:

interface IDog {
    canRun: boolean;
}

interface IBird {
    canFly: boolean;
}

class Dog implements IDog {
    canRun: boolean;
}

class Bird implements IBird {
    canFly: boolean;
}

function createInstance(type: 'bird'): Bird;
function createInstance(type: 'dog'): Dog;
function createInstance(type: string): any {
  switch (type) {
    case 'bird':
        return new Bird();
    case 'dog':
        return new Dog();
  }
}

// concrete is Dog
const concrete = createInstance('dog');

Also I think the factory return type should be interface:

function createInstance(type: 'bird'): IBird;
function createInstance(type: 'dog'): IDog;

Update:

The alternative is to store references to classes:

interface IInterfaces {
    dog: IDog;
    bird: IBird;
}

type IFactory<T> = {
    [P in keyof T]: new() => T[P];
}

let factory: IFactory<IInterfaces> = {
    dog: Dog,
    bird: Bird
}

let dog = new factory.dog();
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download