Skip to content

noImplicitOverride does not complain on abstract methods #44457

Description

@Lusito

Bug Report

When using noImplicitOverride, I would expect a missing override to complain for abstract methods as well.

🔎 Search Terms

noImplicitOverride abstract

Found #13729, which states "Let's say no for now.", but I would argue against that.

🕗 Version & Regression Information

TypeScript 4.3.2 and Nightly

  • I was unable to test this on prior versions because this is a new feature

⏯ Playground Link

Playground link with relevant code

You'll need to manually set the tsconfig option in the Playground, as the share link doesn't seem to contain that option.

💻 Code

abstract class Hello {
    abstract doesNotComplain(): void;
}

class World extends Hello {
    // should complain here for missing override keyword
    doesNotComplain() {}
}

🙁 Actual behavior

With noImplicitOverride=true, tsc is fine with the above snippet

🙂 Expected behavior

With noImplicitOverride=true, it should complain about the missing override keyword.

Reasoning

I can add an override keyword for implementations of abstract methods. So if I can define it as override, there must be an implicit override if I don't write it manually and the option noImplicitOverride should catch that.

Why do I want this to happen aside from the confusing/incorrect wording of the option?

If I use the override keyword manually, I get an error if the base class removes the abstract method declaration and I can properly update my code. If I didn't have the override keyword, I would have dead code, which needs to be handled differently in newer versions of the base class (for example by registering an event listener instead of implementing an abstract method).

Activity

  1. MartinJohns commented on Jun 6, 2021

    @MartinJohns
    Contributor

    Related: #44439

  2. Kingwl commented on Jun 6, 2021

    @Kingwl
    Contributor

    It's working as expected.

    You can see this thread to learn more.

  3. Lusito commented on Jun 6, 2021

    @Lusito
    Author

    Martin Johns (@MartinJohns) that's a different issue and has nothing to do with this one.

    Wenlu Wang (@Kingwl) Thanks for the info. Looking at the PR description, it was at least not very clear and the comment you highlighted seems more about semantics than about usefulness. I would expect noImplicitOverride to help me find possible errors.
    I guess if this is not wanted in noImplicitOverride, It might be possible to create an eslint rule to add that extra safety.

  4. RyanCavanaugh commented on Jun 7, 2021

    @RyanCavanaugh
    Member

    (Crossposting this comment) This is intentional. The mental model to have in place here is, "If I typo this method name, what will happen?"

    If you typo the name of an abstract member (assuming you're in a concrete class), you'll get an error, because you failed to implement all abstract members. override isn't necessary to prevent you from making this mistake, so you don't need to write override in this case.

    If you typo the name of an optional member, you'll now have calculateHeight and cacluateHeight, and the latter will just go silently uncalled forever. override is necessary to prevent you from making this mistake, so when overriding an optional member, you should be writing override.

  5. Lusito commented on Jun 7, 2021

    @Lusito
    Author

    Ryan Cavanaugh (@RyanCavanaugh)
    So your scenario is:

    1. Write a new class, implement abstract method, make a typo
    2. Wanting to get informed about typo.

    While I would say, that this is a perfectly valid scenario, I would say the more important scenario is:

    1. Write new class, implement abstract method, test => all good
    2. Update dependency, abstract method has been renamed or removed
    3. Wanting to get informed about this change.

    When implementing an abstract method for the first time, you usually make sure it works correctly, so you're less likely to make a mistake here. But if you update a dependency and the abstract method has been removed from the base class (not just renamed), you will at best be left with dead code, at worst with a broken feature.

  6. RyanCavanaugh commented on Jun 7, 2021

    @RyanCavanaugh
    Member

    I don't disagree.

    It can also be argued that you should only be able to write override foo() in places where super.foo() is legal to write, and that doesn't apply for abstract members.

    People will have varying expectations and at the end of the day we have to pick one for clarity and folks who had different expectations will have to adjust a bit.

  7. Lusito commented on Jun 7, 2021

    @Lusito
    Author

    That is true, though at least Java uses @Override for interfaces as well.

    So we either need to introduce a new keyword "implement" (not fixed on the naming), which can be used for methods, which implement abstract methods or optional properties, or we should handle both cases in exactly the same way under one keyword "override". I'd be fine with implement foo() {} for all places, where super.foo() is not legal.

  8. typescript-bot commented on Jun 10, 2021

    @typescript-bot
    Contributor

    This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  9. locked as resolved and limited conversation to collaborators on Oct 21, 2025
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

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions