I encountered new()
in the official document here about generics.
Here is the code context:
function create(c: { new(): T; } )
new()
describes a constructor signature in typescript. What that means is that it describes the shape of the constructor.
For instance take {new(): T; }
. You are right it is a type. It is the type of a class whose constructor takes in no arguments. Consider the following examples
function create<T>(c: { new(): T; } ): T {
return new c();
}
What this means is that the function create
takes an argument whose constructor takes no arguments and returns an instance of type T
.
function create<T>(c: { new(a: number): T; } ): T
What this would mean is that the create function takes an argument whose constructor accepts one number a
and returns an instance of type T.
Another way to explain it can be, the type of the following class
class Test {
constructor(a: number){
}
}
would be {new(a: number): Test}
So in the documentation is mentions that the syntax is for "When creating factories in TypeScript using generics".
If you look at a larger example that they have:
class BeeKeeper {
hasMask: boolean;
}
class ZooKeeper {
nametag: string;
}
class Animal {
numLegs: number;
}
class Bee extends Animal {
keeper: BeeKeeper;
}
class Lion extends Animal {
keeper: ZooKeeper;
}
function findKeeper<A extends Animal, K> (a: {new(): A;
prototype: {keeper: K}}): K {
return a.prototype.keeper;
}
findKeeper(Lion).nametag; // typechecks!
a: {new(): A
// is actually creating a new instance of the type A which is extending Animal.
// it is necessary to refer to class types by their constructor functions
The new keyword is used to create an instance of a class, so in it's simplest form:
class SimpleClass {
}
Would be constructed as follows:
let simpleClassInstance = new SimpleClass();
This is all well and good, but how do you create an instance of a generic class, i.e:
class SimpleClassFactory< T > {
static create( T ) {
return new T(); // compile error could not find symbol T
}
}
Would be used as follows:
let simpleClassInstance = SimpleClassFactory.create(SimpleClass);
Here, we are attempting to use the class definition to create an instance of a class. This will generate a compile error.
So we need to refer to the type by it's constructor signature:
class SimpleClassFactory< T > {
static create( type: { new(): T ;} ) {
return new type(); // succeeds
}
}