Skip to content

Abstract methods #2947

Closed
Closed

Description

As a continuation of #6, which allows the abstract modifier on class declarations, we should extend this to class methods.

Relevant points:

  • An abstract method may only be declared in an abstract class
  • abstract methods may not have implementations
  • abstract methods may not be private, but may be protected
  • It is an error to invoke an abstract method via super in a derived clas
  • Fields may not be abstract
  • Property getters / setters may not be abstract
  • A class must be marked abstract if it does not overwrite all of its abstract base class's abstract methods
  • All overloads of a method must have, or not have, the abstract modifier
  • Static methods may not be abstract
  • abstract modifier must come after public or protected modifier

Secondary clarifications:

  • abstract has no impact on assignability / subtype / supertype relations

Activity

  1. ddotlic commented on May 1, 2015

    @ddotlic

    I was just about to comment on asking for something like this, it's not yet reached a pain point in the project I'm working on (due to the size) but might soon.

    I simply want to make sure I don't forget to override an abstract method in a base (base...) class and that's it. The feature can be implemented as rigidly as you want as long as it helps me code better - meaning I really don't care about other subtleties as mentioned in #6 though I'm aware some are important to clarify before implementation begins as it clashes with some of the JS oddities.

    TypeScript is shaping up to be a really great language (seeing what you've started with - JavaScript - can't be considered great unless you're heavily drunk 😉 )

  2. CKGrafico commented on Jun 18, 2015

    @CKGrafico

    Anything new about this?

  3. mhegazy commented on Jun 18, 2015

    @mhegazy
    Contributor

    Arthur Ozga (@aozgaa) is looking into this

  4. aozgaa commented on Jun 19, 2015

    @aozgaa
    Contributor

    I've posted an updated proposal in #3578 and made a pull request in #3579. Take a look and let me know what you think!

  5. tinganho commented on Jul 9, 2015

    @tinganho
    Contributor

    Static methods may not be abstract

    Ryan Cavanaugh (@RyanCavanaugh) Is there a way I can write a contract where on extending class's static methods has a certain signature?

    export abstract class ComposerContent<Props, States, T> extends ReactComposerComponent<Props, States> {
       static abstract fetch(): string;
    }
    

    React seem to want to put a lot of stuff as static members(GrahpQL, Relay). And I want some autocompletion on those only by extending a class.

  6. RyanCavanaugh commented on Jul 9, 2015

    @RyanCavanaugh
    MemberAuthor

    Is there a way I can write a contract where on extending class's static methods has a certain signature?

    There isn't. Let us know if you see other cases where this would be useful - we generally didn't see a need for it.

  7. added
    CommittedThe team has roadmapped this issue
    and removed
    RevisitAn issue worth coming back to
    on Jul 9, 2015
  8. tinganho commented on Jul 11, 2015

    @tinganho
    Contributor

    Ryan Cavanaugh (@RyanCavanaugh) I have another question about abstract classes. I wonder how I define a function that accepts a derived abstract class that is not abstract and the function should also "new" it.

    The following doesn't work:

    function testDerived<T extends typeof ComposerComponent>(DerivedClass: T) {
        new DerivedClass(); // error
    }
    function testDerived(DerivedClass: typeof ComposerComponent) {
        new DerivedClass(); // error
    }
  9. RyanCavanaugh commented on Jul 11, 2015

    @RyanCavanaugh
    MemberAuthor

    function testDerived(DerivedClass: new() => ComposerComponent) {

  10. tinganho commented on Jul 29, 2015

    @tinganho
    Contributor

    Ryan Cavanaugh (@RyanCavanaugh) does it makes sense with optional abstract methods? I want to define an abstract class with some abstract methods on it. But I want a derived class doesn't need to implement all of the methods.

    Since you allow optional on interfaces I think it makes very much sense to allow it on abstract methods as well.

  11. RyanCavanaugh commented on Jul 29, 2015

    @RyanCavanaugh
    MemberAuthor

    We don't plan to support optional class methods. It's too confusing from a consumer perspective.

    You can write something like this if you want (note that these would have to be instance members, not prototype methods):

    class MyClass {
      foo: () => number = undefined;
    }
  12. battmanz commented on Sep 28, 2015

    @battmanz

    Why can't property getters / setters be abstract?

  13. mhegazy commented on Sep 28, 2015

    @mhegazy
    Contributor
  14. vyshkant commented on May 15, 2016

    @vyshkant

    Is there a way I can write a contract where on extending class's static methods has a certain signature?

    There isn't. Let us know if you see other cases where this would be useful - we generally didn't see a need for it.

    Ryan Cavanaugh (@RyanCavanaugh) The case when abstract static method can be useful is next.

    I want to have one abstract class and two child classes.
    Each child should have some class-dependent value (not instance-dependent).
    I want to access this value without creating an instance of class.
    I want to access this value when I don't know which specific child-class I'm accessing (examples below).
    So I want to be sure, that every child of an abstract class has this static method.

    abstract class Abs {
        /*public static getSomeValue() {
            return null;
        }*/
    }
    
    class Child1 extends Abs {
        public static getSomeValue() {
            return 'Some value of class Child1';
        }
    }
    
    class Child2 extends Abs {
        public static getSomeValue() {
            return 'Some value of class Child2';
        }
    }
    
    class Factory {
    
        public static getClasses(): (typeof Abs)[] {
            return [
                Child1,
                Child2
            ];
        }
    }
    
    var classes = Factory.getClasses();
    
    for (var index in classes) {
        if (classes.hasOwnProperty(index)) {
            classes[index].getSomeValue();
        }
    }

    So there is two ways to be sure that classes[index].getSomeValue();will not cause an error:

    1. Implement the same method in abstract class (commented out in example above). De facto this method will be a kind of stub.
    2. Check an availability of getSomeValue method every time before call, that not seems to be good idea.

    Declaring abstract static method in abstract class will resolve the problem.

  15. ChiriVulpes commented on Jul 8, 2016

    @ChiriVulpes
    Contributor

    The one use case I would really like abstract static for:

    abstract class Serializable {
        abstract serialize (): Object;
        abstract static deserialize (Object): Serializable;
    }
    

    Unless there's another way I can go about writing a simple Serializable interface like this?

  16. troywweber7 commented on Mar 8, 2017

    @troywweber7

    Any progress on allowing abstract static methods?

  17. RyanCavanaugh commented on Mar 8, 2017

    @RyanCavanaugh
    MemberAuthor

    Please log a new suggestion issue for abstract static methods - we generally don't track upvotes on comments on closed issues!

  18. troywweber7 commented on Mar 8, 2017

    @troywweber7

    Anton Dyshkant (@vyshkant) @Aarilight did your use cases go away, or are they still valid? If they are, then we should submit an issue as Ryan Cavanaugh (@RyanCavanaugh) suggests. If one of you guys starts the issue, I may eventually have a use case to add to it.

  19. vyshkant commented on Mar 11, 2017

    @vyshkant

    @Aarilight , Troy (@troywweber7) , Ryan Cavanaugh (@RyanCavanaugh) I have created suggestion issue #14600 about this problem.

  20. locked and limited conversation to collaborators on Jun 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    CommittedThe team has roadmapped this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions