How is it possible to pass an array of functions that return object of some type. In another words - array of constructors?
What I want to do is something like this:
constructor(name: string, systems: Array<Function>){
this.system = new systems[0]();
}
but I got an error Cannot use 'new' with an expression whose type lacks a call or construct signature.
and as I understand I should somehow let compiler know what type of objects that constructor returns but I don't know how.
Assuming RJM's answer, here is a bit extended example of what I mean:
interface System{
name: string;
}
interface Component{
blahblha: string;
}
class Doh implements Component{
blahblha: string;
}
class Bar implements System{
name: string = 'bar';
}
class Blah implements System{
name: string = 'foo';
}
class Foo {
systems: Array<System>;
constructor(bars: Array<()=>System>) {
for (let i in bars){
this.systems.push(new bars[i]()); // error: only a void functions can be called with the 'new' keyword.
}
}
}
var foo = new Foo([Blah]); // error: Argument of type 'typeof Blah[]' is not assignable to parameter of type '(() => System[]'. Type 'typeof Blah[]' is not assignable to type '() => System'.
I want to ensure that Foo.systems
will be populated only with instances of objects that implements System interface. So I should have error doing something like new Foo([Doh]);
but I'm getting error even when passing Blah
If you want to instantiate classes you will have to refer to it's constructor using the new keyword.
function factory(constructors: { new (): System }[]) {
let constructed = constructors.map(c => new c());
}
interface System {
name: string;
}
class SomeClass implements System {
name: string;
constructor() { }
}
class SomeOtherClass implements System {
name: string;
constructor() { }
}
let a = factory([SomeClass, SomeClass, SomeClass, SomeOtherClass]);
The factory function will receive a list of constructors that can create something of that satisfies the System interface.
Calling the method with a class that does not implement System will result in the error you are receiving now.
class AnotherClass {}
factory([AnotherClass]); // error
Structural typing works as well, so you don't have to implement the interface explicitly.
class AnotherClass {
name: string
}
factory([AnotherClass]);
To make the code a little bit cleaner you can move the interface described for the constructors parameter to an interface declaration.
// an interface that describes classes that create instances that satisfy the System interface
interface CreatesSystem {
new (): System
}
interface System {
name: string;
}
function factory(constructors: CreatesSystem[]) {
let constructed = constructors.map(c => new c());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With