-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Enhancement: [no-redundant-property-definitions] Rule to detect redundant visibility definitions in derived classes #10825
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
Comments
First, this rule is not type-aware and your proposal does not seem to address a core problem that's worth making the rule type-aware, so we are discussing a new rule, not an existing rule extension. Second, how would that be different from this? class A {
a = 1;
}
class B extends A {
a = 2;
} Or this? class A {
a;
constructor(a) {
this.a = a;
}
}
class B extends A {
a = 2;
} Or any other combination of these features? Why is this proposal specific to parameter properties, and not reinitialization of inherited class fields at large? Should we just have a rule that reports all kinds of class field overwriting? |
Thanks @Josh-Cena , and I assume in your code snippets, all class B extends class A since currently it's confusing that non-inherited classes are irrelevant to this proposal. First, I agree with you to treat this proposal as a new rule rather than a rule extension. Second, IMO rules are about warning developers of potentially unclear and unintentional code. In both of the code snippets you provided:
However, in the context of this proposal, that is, in the following code: class A {
constructor(public a: string) {}
}
class B extends A {
constructor(public a: string, public b: any) {
super(a);
}
}
This proposal is not about class field overwriting. This proposal intends to report an implicitly duplicated re-assignment due to the misuse of the TS feature
This proposal was inspired by an existing rule Hope this makes things more clear :) |
Right, and I think what we're saying is:
I'm mildly in favor of a generalized rule, like class Base {
constructor(public a: string) { }
}
class Derived extends Base {
constructor(public a: string) {
super(a);
}
}
Agreed this new rule would need type information. There are subtle runtime differences, so I don't think the rule couldn't auto-fix. It could only report with suggestions. P.S. @Josh-Cena I edited in |
@JoshuaKGoldberg Did you mean code like: class A {
public a: string;
}
class B extends A {
public a: string;
} I think this is a good idea that expands the original use case and strengthens the implementation value.
Thank you for your link, from which I learned that TypeScript can compile a class property declaration to I also attached a playground link that demonstrates under both compile options, any further audition to class property in the parent class will be reset by the derived class. And if this rule is going to be expanded to |
Coming back to this, we chatted a bit as a team and think:
We don't have the maintenance budget to work on every useful-in-some-cases rule proposed. If a lot of community members pitch in over the next few months expressing then that would be a signal we should put this one in scope. If not it might make more sense to tackle as a third-party plugin. I've added the |
Thank you @JoshuaKGoldberg, I agree that class inheritance is slowly becoming less popular, which make this proposal less useful. JS/TS just contains too many features that developers had to choose from. While waiting for any further community response, may I try to implement it at the same time, and maybe will submit a PR in ~1 month? |
You're absolutely welcome to try implementing it, that's a great idea! A lot of rule proposals have been improved -even drastically changed- by prototypes in that way. The one sticking point is that many Suggestion: you might want to make a third-party plugin that folks can use to try it out. It'd be good marketing to try to get more attention to this issue. Plus if this issue is wontfixed you'd have a plugin folks can use to opt into the proposed rule(s). |
Before You File a Proposal Please Confirm You Have Done The Following...
My proposal is suitable for this project
Link to the rule's documentation
https://typescript-eslint.io/rules/parameter-properties/
Description
TL;DR
This issue proposes the following changes to the rule
parameter-properties
:parameter-property
under the class inheritance:no-unnecessary-parameter-property-assignment
to this rule.Background
Currently, the rule
parameter-properties
strictly reports the following TS parameter property usage whenOptions.prefer
is set toparameter-property
and conditions marked in comments are met:which expects it to be refactored as the following (Though no auto-fix was provided) to prefer
parameter-property
:However, the TS feature
parameter-property
comes with an error-prone usage (duplication):A developer would not intentionally write code like this, so the rule
no-unnecessary-parameter-property-assignment
detects it.Motivation
During our feature usage analysis, we found another error-prone usage involving the
super
call (that is, the class inheritance):causing the assignment expression
this.a = a
appears twice in classFoo
and classBar
respectively (See JS code in this playground).This is not a niche proposal since a real-world case can be found in a famous repository
BabylonJS/Babylon.js
, wheredefaultViewer.ts
declares a classDefaultViewer
that extends from a parent classAbstractViewerWithTemplate
.DefaultViewer
can be traced back to classAbstractViewer
inviewer.ts
.AbstractViewer
declares a parameter property withpublic containerElement: Element
.DefaultViewer
also DECLARES a parameter property withpublic containerElement: Element
and sends it to thesuper()
call.no-unnecessary-parameter-property-assignment
detects.This case is considered a bad practice by us because, on the contrary, we also found the following best practice as demonstrated by the repository
glideapps/quicktype
, whereDart.ts
classDartRenderer
-extends->ConvenienceRenderer.ts
classConvenienceRenderer
-extends->Renderer.ts
classRenderer
.targetLanguage
is markedprotected readonly
in the parent class and not marked in the following derived classes.Proposal
Given the motivation described above, we would like to (mainly) propose the enhancement of the unnecessary-check under the class inheritance:
super
call.This check benefits a better use of the feature
parameter-property
.Optional Goal
Like the rule
no-unnecessary-parameter-property-assignment
, a developer would not intentionally write duplicated code once they determined toprefer: 'parameter-property'
. We consider violations of best practices like these should be implemented seamlessly and automatically without another rule to turn on.The base rule
parameter-properties
was discussed in 2019 and implemented in 2022, and the ruleno-unnecessary-parameter-property-assignment
was discussed in 2023 and introduced later in 2024. We have read all discussions in PRs and issues and found that merging them into one rule was not discussed previously. By the chance of enhancing the base rule, we would like to pose the discussion for a more concise and compact rule set.Fail
Pass
Additional Info
Current rules can not detect the bad practice discussed in this proposal.
The text was updated successfully, but these errors were encountered: