Sergei Basharov Sergei Basharov - 5 months ago 22
Javascript Question

How to type an array with classes in TypeScript?

I have an app that initializes by running its method

.init(params)
like this:

app.init([TopBar, StatusBar, MainArea]);


Where
TopBar
,
StatusBar
and
MainArea
are classes, not instances of classes. Each of these classes implements the same interface
IComponent
.

I want to instantiate objects from the passed classes in the
.init(params)
method, like this:

init(params: IComponent[]): void {
params.map(function (component) {
let comp = new component();
this.components[comp.constructor.name] = comp;
}, this);


The issue is that as these are not instance, TypeScript doesn't know their types and throws an error:


error TS2345: Argument of type '(typeof TopBar | typeof StatusBar |
typeof MainArea)[]' is not assignable to parameter of type
'IComponent[]'.


How do I fix the code so that I could pass an array of classes that implement some interface to a method?

Answer

There is a working typescript playground (run it to get alert with result)

what we need is to create a custom type InterfaceComponent. That will be expected as an array of the init() method

interface IComponent { }
class TopBar    implements IComponent { }
class StatusBar implements IComponent { }
class MainArea  implements IComponent { }

// this is a type we want to be passed into INIT as an array
type InterfaceComponent = (typeof TopBar | typeof StatusBar | typeof MainArea);

class MyClass {

  components: {[key:string] : IComponent } = {};

  init(params: (InterfaceComponent)[]): void {
    params.map((component) => {
        let comp = new component();
        this.components[comp.constructor["name"]] = comp;
    }, this);
  }
}

let x = new MyClass();
x.init([TopBar, StatusBar, MainArea])

alert(JSON.stringify(x.components))

Check it here

Comments