-
-
Notifications
You must be signed in to change notification settings - Fork 475
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
feat(js_analyze): add lint/noEnum
#3653
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used noConsole
as inspiration to write diagnostic and documentation, but I understand it can feel a little lacking.
I'm open to suggestions!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it would be helpful to suggest an alternative in this case. For example, recommending a TypeScript object as a replacement for enums
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution and a good start! I've added a few comments. :)
/// BAR = 'bar' | ||
/// } | ||
/// ``` | ||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add a valid case like below?
/// ### Valid
///
/// ```js
/// const Foo = {
/// BAR: 'bar',
/// };
/// ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it would be helpful to suggest an alternative in this case. For example, recommending a TypeScript object as a replacement for enums
CodSpeed Performance ReportMerging #3653 will not alter performanceComparing Summary
|
"Don't use "<Emphasis>"enum"</Emphasis> | ||
}, | ||
) | ||
.note(markup! { | ||
"Prefer using JavaScript objects or TypeScript unions over enums." | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The diagnostics are good, however we miss the explanation of the error. Here, we need to explain why a user shouldn't use enums.
Please refer to our rule pillars: https://biomejs.dev/linter/#rule-pillars
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @nickfla1, I noticed 5694370
(#3653). The reason should be added to the diagnostic too :)
lint/noEnum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some questions / suggestions:
- We already have a rule that bans
const enum
. I tis a recommended rule.
Should we restrictnoEnum
to regular enums?
This could avoid double diagnostics and more flexibility: a user could allowconst enum
and disallowenum
. - I think we could allow
declare enum
and enums in TS declaration files (See rules such asnoEvolvingTypes
that checks if a file is a declaration/definition file) and in any ambient context (we have ais_ambient
method that can be applied on aTsEnumdeclaration
node)
I think I agree on everything you've said! I'll wait for confirmation from @ematipico before implementing it in the PR |
Sure go ahead |
let source_type = ctx.source_type::<JsFileSource>().language(); | ||
let is_declaration = source_type.is_definition_file(); | ||
|
||
if is_declaration { | ||
return None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should check it before checking for const/ambient enums.
let is_ambient = enum_decl.is_ambient(); | ||
|
||
if is_const_decl || is_ambient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let is_ambient = enum_decl.is_ambient(); | |
if is_const_decl || is_ambient { | |
if is_const_decl || enum_decl.is_ambient() { |
@@ -23,7 +23,7 @@ invalid.ts:1:1 lint/nursery/noEnum ━━━━━━━━━━━━━━━ | |||
│ ^ | |||
4 │ | |||
|
|||
i Prefer using JavaScript objects or TypeScript unions over enums. | |||
i Prefer using JavaScript objects, TypeScript unions or const enums over plain enums. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const enum
have some important caveat (cf noConstEnum
, docs). Moreover, we recommend noConstEnum
.
Thus, I think it is not a good idea to suggest using them here.
i Prefer using JavaScript objects, TypeScript unions or const enums over plain enums. | |
i Prefer using JavaScript objects or TypeScript unions over plain enums. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. I left my last suggestions :)
.note(markup! { | ||
"Enums will get compiled into JavaScript code, which can increase bundle size and cause side-effects in the codebase." | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not always true because some bundlers such as ESBuild or TSC are able to inline some enums. Thus, this can even be the reverse: using TS enum can improve code size and performance.
I suggest removing this note.
.note(markup! { | ||
"Prefer using JavaScript objects or TypeScript unions over plain enums." | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I propose this rephrasing:
.note(markup! { | |
"Prefer using JavaScript objects or TypeScript unions over plain enums." | |
}) | |
.note(markup! { | |
"Use JavaScript objects or TypeScript unions instead." | |
}) |
Also, to follow the order of our rule pillars, I could put this note after other notes.
I have updated the docs and notes accordingly. I am wondering what's the best approach to solve the conflict on that file since it's autogenerated. |
Merge from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me :) Thanks for your contribution!
Happy to help! Thank you for your support and suggestions :) |
Summary
Closes #3651
Added the
noEnum
TypeScript rule to disallow of enums altogether.Test Plan
Run
cargo test
.quick_test
changes to test this rule: