I want to have a function like:
createEntity<TEntity>(): TEntity {
return new TEntity();
}
In C#, we could write:
void TEntity CreateEntity<TEntity>() where TEntity : new()
How can I do this in TypeScript?
You can specify one or more constraints on the generic type using the where clause after the generic type name. The following example demonstrates a generic class with a constraint to reference types when instantiating the generic class.
where T : new() Means that the type T must have a parameter-less constructor. Having this constraint will allow you to do something like T field = new T(); in your code which you wouldn't be able to do otherwise. You then combine the two using a comma to get: where T : class, new()
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function.
A type constraint on a generic type parameter indicates a requirement that a type must fulfill in order to be accepted as a type argument for that type parameter. (For example, it might have to be a given class type or a subtype of that class type, or it might have to implement a given interface.)
The only way shown in the handbook to do something similar to this is to send the class you want to initialize as a parameter to the factory method, and describe it's constructor using the new keyword.
function factory<T>(type: { new (): T }): T {
return new type();
}
class SomeClass { }
let result = factory(SomeClass);
The result will be of type SomeClass.
The constructor of the class will be type checked against the interface defined in the factory method.
If you want to initialize a class that takes a parameter in it's constructor you will have to specify that in the interface given to the factory method.
function factory<T>(type: { new (...args): T }, ...args): T {
return new type(...args);
}
class SomeClass {
constructor(name: string) { }
}
let a = factory(SomeClass, 'John Doe');
This has been answered here in Stack Overflow. To be able to new up a new class using generics, you need to have a guarantee that the type supports instantiation.
You can easily support parameter less constructors using this approach but with constructors that require parameters, it would become less useful as your creatEntity method should have to accept the values for those parameters and pass to the constructor while creating the new instance and as you can see each type can have its own signature for constructor.
class ObjectCreator{
static createEntity<TEntity>(type:{new():TEntity;}):TEntity{
return new type();
}
}
class Person{
firstName:string;
lastName:string;
constructor(){
this.firstName = "TestFirstName";
this.lastName = "TestLastName";
}
}
var person: Person = ObjectCreator.createEntity(Person);
alert(person.firstName);
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