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

Quick fix: "Implement inherited abstract class" should add override keyword to methods #50464

Closed
5 tasks done
KilianB opened this issue Aug 26, 2022 · 9 comments Β· Fixed by #51033
Closed
5 tasks done

Quick fix: "Implement inherited abstract class" should add override keyword to methods #50464

KilianB opened this issue Aug 26, 2022 · 9 comments Β· Fixed by #51033
Labels
Experience Enhancement Noncontroversial enhancements Help Wanted You can do this Suggestion An idea for TypeScript
Milestone

Comments

@KilianB
Copy link

KilianB commented Aug 26, 2022

Suggestion

πŸ” Search Terms

quick fix, code action, override

βœ… Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

When selecting the quick fix action Implement inherited abstract class the generated method signatures should include the override keyword which has been present since version 4.3.

class AdyenPaymentProvider extends LoggingPaymentProvider {
  protected override claimBalance(paymentReference: string, userId?: number | undefined): boolean {
    throw new Error('Method not implemented.');
  }
}

instead of

class AdyenPaymentProvider extends LoggingPaymentProvider {
  protected claimBalance(paymentReference: string, userId?: number | undefined): boolean {
    throw new Error('Method not implemented.');
  }
}

πŸ“ƒ Motivating Example

The autogenerated @Override annotation in Eclipse/java has helped me catch many subtle bug which would have otherwise taken a long time to track down. No harm is done adding the keyword automatically as it will promote the usage of said keyword to a wider audience which will result in better quality code down the line.

In conjunction with changes like #8306 typescript's OOP would simply be less error prone due to stricter enforcements down the line.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Experience Enhancement Noncontroversial enhancements labels Aug 26, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Aug 26, 2022
@RyanCavanaugh RyanCavanaugh added the Help Wanted You can do this label Aug 26, 2022
@a-tarasyuk
Copy link
Contributor

@RyanCavanaugh Should override be used with inherited abstract methods (Playground)? Should we add override when noImplicitOverride is enabled?

/cc @DanielRosenwasser

@RyanCavanaugh
Copy link
Member

There's only one answer that results in no errors, right? I think I'm missing something

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Aug 29, 2022

We don't error on an abstract implementation member that omits override, the design meeting notes make it seem like it was brushed aside.

@JoshuaKGoldberg
Copy link
Contributor

@a-tarasyuk did you mean to ask whether we should only add override when noImplicitOverride is enabled?

@a-tarasyuk
Copy link
Contributor

@JoshuaKGoldberg I meant that override is not required when noImplicitOverride is disabled/enabled for abstract classes.

// @noImplicitOverride: true
abstract class A {
    abstract m(): void;
}

class B extends A {
    // ok
    m(): void {
        throw new Error("Method not implemented.");
    }
}

class A1 {
    m() {}
}

class B1 extends A1 {
    // requires override
    m(): void {
        throw new Error("Method not implemented.");
    }
}

@gabritto
Copy link
Member

We don't error on an abstract implementation member that omits override, the design meeting notes make it seem like it was brushed aside.

@DanielRosenwasser can you link to the design notes or maybe explain why override isn't needed for abstract classes?

@RyanCavanaugh
Copy link
Member

#44457 (comment)

@gabritto
Copy link
Member

#44457 (comment)

Thanks, that makes a lot of sense. So why would we want to put override in the case brought up by this issue? Is it just to convey intention more explicitly? I guess what I want to understand is if we've committed to accepting a fix to this issue, and maybe why.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Oct 19, 2022

Well, I think we kind of messed up with noImplicitOverride under abstract and need to figure out what to do next. The intent of the flag, at least in my formulation, was that if you turned on that flag, everywhere you can write override, you must, and that override was legal if-and-only-iff you could call super.thisMethod();. It seems like for abstract we're not enforcing that correctly on either axis, but it's probably unpalatable to force people to write an override in places where super. isn't legal, or conversely to tell people they can't write override when there "is" a base class method.

Maybe the simplest argument, having put ourselves in this position, is that it's easier to remove the extra overrides than it is to figure out which methods "should" have it, so the quick fix should do the thing that results in the least amount of work in the case where it doesn't match the user's preference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants