Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract methods #2947

Closed
RyanCavanaugh opened this issue Apr 28, 2015 · 18 comments
Closed

Abstract methods #2947

RyanCavanaugh opened this issue Apr 28, 2015 · 18 comments
Labels
Committed The team has roadmapped this issue Suggestion An idea for TypeScript

Comments

@RyanCavanaugh
Copy link
Member

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
@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Apr 28, 2015
@ddotlic
Copy link

ddotlic commented May 1, 2015

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 😉 )

@RyanCavanaugh RyanCavanaugh added the Revisit An issue worth coming back to label Jun 8, 2015
@CKGrafico
Copy link

Anything new about this?

@mhegazy
Copy link
Contributor

mhegazy commented Jun 18, 2015

@aozgaa is looking into this

@aozgaa
Copy link
Contributor

aozgaa commented Jun 19, 2015

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!

@aozgaa aozgaa closed this as completed Jul 1, 2015
@tinganho
Copy link
Contributor

tinganho commented Jul 9, 2015

Static methods may not be abstract

@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.

@RyanCavanaugh
Copy link
Member Author

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.

@RyanCavanaugh RyanCavanaugh added Committed The team has roadmapped this issue and removed In Discussion Not yet reached consensus Revisit An issue worth coming back to labels Jul 9, 2015
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 1.6 milestone Jul 9, 2015
@tinganho
Copy link
Contributor

@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
}

@RyanCavanaugh
Copy link
Member Author

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

@tinganho
Copy link
Contributor

@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.

@RyanCavanaugh
Copy link
Member Author

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;
}

@battmanz
Copy link

Why can't property getters / setters be abstract?

@mhegazy
Copy link
Contributor

mhegazy commented Sep 28, 2015

@battmanz see #4670

@vyshkant
Copy link

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.

@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.

@ChiriVulpes
Copy link

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?

@troywweber7
Copy link

Any progress on allowing abstract static methods?

@RyanCavanaugh
Copy link
Member Author

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

@troywweber7
Copy link

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

@vyshkant
Copy link

@Aarilight , @troywweber7 , @RyanCavanaugh I have created suggestion issue #14600 about this problem.

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Committed The team has roadmapped this issue Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

10 participants