Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript static method in an abstract class to create an instance of self

Let's say I have

abstract class Foo {

}

class Bar1 extends Foo {
    constructor(someVar) { ... }
}

class Bar2 extends Foo {
    constructor(someVar) { ... }
}

I'd like to be able to create a static method that creates an instance of the final class (all constructors would have the same signature). So I want something like:

abstract class Foo {
    public static someAction(someVar) {
        const self = new this(someVar);
    }
}

But this cannot be done because Foo is abstract. Is this at all possible?

UPDATE

What if these classes have their own templates?

abstract class Foo<M> {

}

class Bar1 extends Foo<SomeModel> {...}

Now I want the someAction to know of the type SomeModel. I tried

public static someAction<A, T extends Foo<A>>(this: new (someVar: any) => T, someVar: any): T {
    const self = new this(someVar);
    return self;
  }

But unless I specifically do Bar1.someAction<SomeModel>("blah") the returned result is not available of the type of the data, i.e. Bar1.someAction("blah") doesn't know the data type

like image 733
Kousha Avatar asked Sep 26 '18 08:09

Kousha


People also ask

Can we create static method in abstract class?

Declaring abstract method static If you declare a method in a class abstract to use it, you must override this method in the subclass. But, overriding is not possible with static methods. Therefore, an abstract method cannot be static.

Can I instantiate an abstract class in TypeScript?

TypeScript has the ability to define classes as abstract. This means they cannot be instantiated directly; only nonabstract subclasses can be.

Can I create an instance in static method?

No, we cannot directly access the instance variables within a static method because a static method can only access static members.

Can I declare static method as abstract Why?

A static method belongs to class not to object instance thus it cannot be overridden or implemented in a child class. So there is no use of making a static method as abstract.


1 Answers

You can add an annotation for the this type of the static method. In this case this will refer to the class, and adding an annotation for the this parameter will make the static method visible only on classes that satisfy the constraint (in this case that a constructor with a single argument exists) and it will also help us extract the actual instance type of the class the method is invoked on :

abstract class Foo {
  public static someAction<T extends Foo>(this: new (someVar: any) => T, someVar: any): T {
    const self = new this(someVar);
    return self;
  }
}

class Bar1 extends Foo {

  constructor(someVar: any) {
    super();
  }
}

class Bar2 extends Foo {
  constructor(someVar: any) {
    super();
  }
}
let bar1 = Bar1.someAction(0) // of type Bar1
let bar2 = Bar2.someAction(0) // of type Bar2
like image 97
Titian Cernicova-Dragomir Avatar answered Sep 29 '22 11:09

Titian Cernicova-Dragomir