How to create a child class in TypeScript using parent static method?
Asked Answered
R

1

15

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.

Royroyal answered 15/5, 2018 at 5:23 Comment(0)
R
28

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

Relativity answered 15/5, 2018 at 5:34 Comment(5)
Interesting. I didn't know the syntax this: new () => T. Is there a documentation on this feature somewhere?Aliment
@Aliment It's a mix of several things, this: is the fact that you can specify the type of this on member functions github.com/Microsoft/TypeScript/issues/3694. The new ()=> T is just a constructor signature, (similar to a function signature but callable with new). And the whole things works because of the way parameter inference works ..Relativity
@TitianCernicova-Dragomir, thank you very much for reply. I haven't seen usage of this in the Typescript manual. Do you have link or whatever to read more about the topic?Royroyal
How do you call other static methods when using this? typescriptlang.org/play?#code/…Clingy
That's awesome! I was trying to figure how to do it if I have a constructor. Any suggestion? from function will look like static fromData<T>(this: new (id: number) => T, data: any): T but return Object.assign(new this(id), data); won't work, it has no access to the id.Recaption

© 2022 - 2024 — McMap. All rights reserved.