Reputation: 1163
I have two classes: Model and User. User extends the Model.
export Model {
id: number;
static fromData<T>(data: any): T {
return Object.assign(new Model(), data);
}
}
export User extends Model {
name: string;
sayHi(): string {
return 'Hi, ' + this.name;
}
}
The way I wanted to use it looks like this:
const currentUser = User.fromData(dataFromServer);
const message = currentUser.sayHi();
Method hi() doesn't work because I have created an instance of Model class.
How to use TypeScript generics to get an instance of derived class using base class static method?
I'm planning number of different entities with common.
I saw this answer but I don't know how to pass parameters into a static method in my case.
Upvotes: 18
Views: 8198
Reputation: 249506
Since the static method is on the class itself we have access to the class constructor using this
inside the static method, this
is the class iself. If we constrain the this
parameter to the static method to be a constructor returning T
(this: new ()=> T
) we will get correct typing for the return value. The this
parameter is just for the benefit of the typescript compiler, it will not actually be emitted to JS and you don't have to pass it explicitly:
export class Model {
id: number;
static fromData<T>(this: new () => T, data: any): T {
return Object.assign(new this(), data);
}
}
export class User extends Model {
name: string;
sayHi(): string {
return 'Hi, ' + this.name;
}
}
const currentUser = User.fromData({ id: 10, name: ""});
const message = currentUser.sayHi();
Playground link
Upvotes: 30