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

fix(lint): fix noConfusingVoidType to accept generic types in a union type #611

Merged
merged 7 commits into from
Oct 29, 2023

Conversation

unvalley
Copy link
Member

@unvalley unvalley commented Oct 26, 2023

Summary

Closes #604

Fix noConfusingVoidType

Test Plan

cargo test -p biome_js_analyze no_confusing_void_type

Existing test plans should pass, and add a test case that filed on #604
Update test cases by referencing typescript-eslint no-invalid-void-type test cases.

@github-actions github-actions bot added A-Linter Area: linter A-Website Area: website L-JavaScript Language: JavaScript and super languages labels Oct 26, 2023
@unvalley unvalley marked this pull request as ready for review October 26, 2023 17:57
@unvalley unvalley changed the title fix(lint): noConfusingVoidType should allow generic type in a union type fix(lint): fix noConfusingVoidType to accept generic types in a union type Oct 26, 2023
@Conaclos
Copy link
Member

Conaclos commented Oct 26, 2023

Thanks for your reactivity! :)

Could you explain the nature of the change?
More tests could also help.

I wonder: should we accept all unions including void in a return type and in generic positions?

@unvalley
Copy link
Member Author

unvalley commented Oct 27, 2023

@Conaclos

Could you explain the nature of the change?

If void is included in a union type with generic types, we accept that. (It might be better to check if the contents of the generic type are void)

More tests could also help.

Yes, right. I should add tests in this PR, at least tests for allowGenericTypeArguments option.

I wonder: should we accept all unions including void in a return type and in generic positions?

Probably yes, because we don't have an option to get generic type identifier to accept.

// typescript-eslint no-invalid-void-type test case example
{
      code: 'type voidPromiseUnion = void | Promise<void>;',
      options: [{ allowInGenericTypeArguments: ['Promise'] }],
},

Our noConfusingVoidType is always true to the original no-invalid-void-type 's allowInGenericTypeArguments.

for parent in node.parent()?.ancestors() {
match parent.kind() {
JsSyntaxKind::TS_UNION_TYPE_VARIANT_LIST => {
// checks if the union type contains generic type
for children in parent.descendants() {
Copy link
Member

@Conaclos Conaclos Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure that descendants is the best choice here because it traverses the entire subtree. Instead, we should traverse every constituent and verify if the type is void or a parametrized type with void as argument.

This is the approach used by the ESLint rule.

Otherwise, the implementation is greatly improved :)

@@ -100,7 +100,6 @@ function doSomething(this: void) {}

```ts
function printArg<T = void>(arg: T) {}
printArg<void>(undefined);
Copy link
Member Author

@unvalley unvalley Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an incorrect case. so I remove it.

@unvalley unvalley force-pushed the fix-no-confusing-void-type branch from c5f68cd to 983fb8a Compare October 27, 2023 18:34
@github-actions github-actions bot added the A-Changelog Area: changelog label Oct 27, 2023
chore: restore waste change
@unvalley unvalley force-pushed the fix-no-confusing-void-type branch from 983fb8a to 8ab3842 Compare October 27, 2023 18:39
Comment on lines +125 to +134
JsSyntaxKind::TS_TYPE_ARGUMENT_LIST => {
// handle generic function that has a void type argument
// e.g. functionGeneric<void>(undefined);
let Some(grand_parent) = parent.grand_parent() else {
continue;
};
if grand_parent.kind() == JsSyntaxKind::JS_CALL_EXPRESSION {
return Some(VoidTypeContext::Unknown);
}
return None;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to address the scenario where fn<void>(undefined).
I discovered this issue when I adde tests, so I addressed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What the issue?

Copy link
Member Author

@unvalley unvalley Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this void in function's generic type may confuse developers because the void is useless to be generic.

Referring to typescript-eslint no-invalid-void-type, I think we should make this case invalid.

Previously we treated it as valid: https://github.com/biomejs/biome/pull/611/files#diff-519e64910a99b91258aea6d0bfeb4a64d44dc190c4c15b7f06d9dccc76ec605eL4

@unvalley unvalley requested a review from Conaclos October 27, 2023 19:49
@unvalley unvalley merged commit 96061a8 into biomejs:main Oct 29, 2023
@unvalley unvalley deleted the fix-no-confusing-void-type branch October 29, 2023 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Changelog Area: changelog A-Linter Area: linter A-Website Area: website L-JavaScript Language: JavaScript and super languages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

🐛 noConfusingVoidType: allow Promise<void> | void
2 participants