简体   繁体   中英

abstract static method in TypeScript

I'm looking for a way to implement an abstract static method in TypeScript.

Here an example:

abstract class A {
  abstract static b (): any // error
}

class B extends A {
  static b () {}
}

This is allowed with public , private and protected methods but not with a static method. TypeScript returns the following error:

'static' modifier cannot be used with 'abstract' modifier.ts(1243)

Is there any workaround?

I think the reasoning is generally as follows:

  • Abstract methods are placeholders that a concrete subclass is supposed to implement.

  • The abstract base class will have a concrete method which uses this abstract placeholder, and thus requires it to be implemented; without this, abstract methods make little sense at all. Eg:

     abstract class Foo { bar() { return this.baz() + 1; } abstract baz(): int; }
  • This can only be called on a concrete instance, eg:

     function (foo: Foo) { let val = foo.bar(); ... }

    The result will be different here depending on what concrete subclass of Foo you get, but it's all guaranteed to work.

Now, what would this look like with static methods?

abstract class Foo {
    static bar() {
        return this.baz() + 1;
    }

    abstract static baz(): int;
}

function (F: typeof Foo) {
    let val = F.bar();
    ...
}

This looks somewhat logical and like it should work, shouldn't it? But:

  • If you write this, there's basically no difference to passing instances of classes, except for the awkward typeof typing. So, why?
  • If you never instantiate the class, what's the point of a class?
  • If your static method does instantiate an object, if it acts as an alternative constructor —which is entirely legitimate—then calling F.bar() to get a new instance, you'd expect to get an instance of F , but you might be getting an instance of some subclass of it. And that's arguably not desired.

To rephrase the chain of argument here:

  • If you're going to use static methods at all, they should act as alternative constructors and return an instance, otherwise they have little business being part of the class.
  • Alternative constructors should return an instance of the class that you called them on. Calling F.bar() and not getting an instance of exactly F is… weird?
  • If you're going to call static alternative constructors on classes, you're going to want to call them on specific classes and not variables as shown above, because otherwise you really won't know what you're getting (see point above).
  • Therefore, there's no real use case for an abstract static method, either as direct alternative constructor nor as helper function for one, since that would lead to a violation of one of the above points one way or another.

As far as I see, this is pretty much the classical thinking that lead to abstract static methods not being a thing. Certain technical limitations in Java may have contributed to that and/or lead to said technical limitations in the first place.

In Javascript one can argue that this makes less sense, since even classes are objects and it would be entirely feasible to use them as described above, and in certain situations it may even make sense. But here we are.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM