Skip to content

Allow readonly / const keyword for class member function definitions #47003

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

Closed
5 tasks done
thw0rted opened this issue Dec 3, 2021 · 4 comments
Closed
5 tasks done

Allow readonly / const keyword for class member function definitions #47003

thw0rted opened this issue Dec 3, 2021 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@thw0rted
Copy link

thw0rted commented Dec 3, 2021

Suggestion

πŸ” Search Terms

readonly class member function assign overwrite

βœ… 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

Class definitions should provide a way to protect member function definitions from accidentally being overwritten.

The syntax public readonly callback() { ... } is currently an error, as is public const callback() { ...}. I can see where some people might get confused or surprised about the use of one of these keywords, thinking it applies to the return value, so I'm open to other suggestions -- but frankly, the current behavior is surprising.

πŸ“ƒ Motivating Example

This is currently valid code:

class Foo {
  callback() { ... }
  start() {
    let callback = x => { this.doX(x); };
    if (someCondition) {
      // Oops, I meant to type "callback = ..."
      this.callback = y => { this.doY(y); };
      // I just overwrote the implementation of `Foo#callback`
    }
    library.doThing(callback);
  }
}

As far as I can tell, the only way to catch the above logic error is to declare all methods of Foo as const member variables, e.g.

class Foo {
  public readonly callback;
  constructor() {
    this.callback = (function() { ... }).bind(this);
  }
}

πŸ’» Use Cases

This probably doesn't actually come up that often in the wild, but it can produce difficult-to-trace logic errors at runtime when it does. The workaround posted in the previous section is unwieldy, and some syntactic sugar would make the feature more likely to be used.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Dec 3, 2021
@RyanCavanaugh
Copy link
Member

#22315. Missing search term - these are commonly called "methods"

@thw0rted
Copy link
Author

thw0rted commented Dec 6, 2021

Thanks @RyanCavanaugh , I could swear I'd tried "method" as well but maybe it was part of some other combination of terms.

That other issue looks like it was tagged "awaiting feedback" nearly 3 years ago. It has received 34 thumbs-up reactions and garnered a bit of discussion, but it doesn't look like the team has participated at all. Is this on the radar? Is the problem not widespread enough to take any action?

@RyanCavanaugh
Copy link
Member

34 votes in 3 years is pretty low-traffic as far as suggestions go, especially for one with fairly invasive syntax changes. I don't think action here is particularly likely.

@thw0rted
Copy link
Author

thw0rted commented Dec 8, 2021

That's more than fair. I may take this over to typescript-eslint and see if they think it's worth a rule. On reflection, it might feel more like an "antipattern" than a language feature anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants