What I want to achieve is to have a function with a generic type T
and to be able to create objects of said type.
I figured I had to use construct signatures and I thought that I could use a generic constraint to define that my class needs a constructor. Yet, this did not work, as shown in Example 1. Instead, if I define my function's parameter to have the construct signature as type instead of using a generic constraint, it suddenly work.
I still cannot make out why Example 1 does not work. I found this StackOverflow Q&A which talks about things such as static side and instance side of a class, which are in turn in more detail explained here. Nevertheless, I cannot make out how exactly this relates to my problem.
I thought that it might be due to the fact that type
may describe an instance of T
(and not the class itself), but then a colleague came up with Example 3, which (for whatever reason) works!
I hope somebody can shed some light on this for me.
Example 1 (not working): The following does not work (create(Person)
gives the error Argument of type 'typeof Person' is not assignable to parameter of type 'new (...args: any[]) => typeof Person'.
:
class Person {
public name: string
constructor(name: string = '') {
this.name = name
}
}
function create<T extends { new(...args:any[]) : T }> (type : T) : T {
return new type()
}
console.log(create(Person))
Example 2 (working):
class Person {
public name: string
constructor(name: string = '') {
this.name = name
}
}
function create<T> (type : { new(...args:any[]) : T } ) : T { // this line has been changed
return new type()
}
console.log(create(Person))
Example 3 (working):
class Person {
public name: string
constructor(name: string = '') {
this.name = name
}
}
function create<T extends { new(...args:any[]) : any }> (type : T) : InstanceType<T> { // this line has been changed
return new type()
}
console.log(create(Person))