Skip to content

fix(useDestructuring): exclude plain assignments and non-iterable index types#9457

Closed
Vadaski wants to merge 4 commits intobiomejs:mainfrom
Vadaski:fix/8480-use-destructuring-illegal-cases
Closed

fix(useDestructuring): exclude plain assignments and non-iterable index types#9457
Vadaski wants to merge 4 commits intobiomejs:mainfrom
Vadaski:fix/8480-use-destructuring-illegal-cases

Conversation

@Vadaski
Copy link
Copy Markdown

@Vadaski Vadaski commented Mar 12, 2026

Summary

Fixes #8480.

The useDestructuring rule was incorrectly suggesting illegal destructuring in two cases:

Case 1: Plain assignment expressions

type SomeObj = { thing: number };
let thing: SomeObj;
const other: SomeObj = { thing: 5 };
thing = other.thing; // ← was incorrectly flagged

thing = other.thing cannot be converted to const { thing } = otherthing is already declared. The destructuring form ({ thing } = other) changes binding semantics and may not be a valid refactor. Fixed by restricting the rule query to JsVariableDeclarator only (skipping JsAssignmentExpression).

Case 2: Numeric index on index-signature types

type NotArray = { [x: string]: string };
const first: NotArray = { "0": "string" };
const second = first[0]; // ← was incorrectly flagged for array destructuring
const [ third ] = first; // Type error: 'NotArray' must have '[Symbol.iterator]()'

Array destructuring was suggested even for index-signature objects that have no iterable protocol. Fixed by resolving the declared type of the object expression and returning false for non-iterable types like TsObjectType. any-typed expressions are treated conservatively (suggestion still shown).

Test Plan

  • Added valid.js and valid.ts test cases for both regression scenarios.
  • All 4 use_destructuring snapshot tests pass: cargo test -p biome_js_analyze use_destructuring.
  • Updated invalid.js.snap to reflect removed false-positive cases.

This PR was written with Claude Code AI assistance (code generation + compilation fix).

🤖 Generated with Claude Code

…ex types

- Skip rule for assignment expressions (not variable declarations), since
  `foo = obj.foo` cannot be safely refactored to `({ foo } = obj)` for
  pre-declared variables.
- Add type-based guard for numeric computed member access: only suggest
  array destructuring when the object type is array-like or iterable.
  Index-signature objects (e.g. `{[key: string]: string}`) are now
  correctly excluded.

Fixes: biomejs#8480

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: 54d0d9c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Mar 12, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 12, 2026

Walkthrough

The useDestructuring lint now runs on Semantic<JsVariableDeclarator> and consults the semantic model to decide when to suggest destructuring. It no longer suggests destructuring for plain assignments to pre-declared variables or for numeric-index access on non-iterable/string-index-signature types (which would make array destructuring a type error). Array/tuple/iterable support is determined via model-aware helpers; tests were added/updated to cover these excluded cases and to avoid recursion on cyclic type aliases.

Possibly related PRs

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the main change: fixing useDestructuring to exclude plain assignments and non-iterable index types.
Description check ✅ Passed The description is directly related to the changeset, explaining the two specific cases fixed with code examples and test plan details.
Linked Issues check ✅ Passed The code changes fully address issue #8480's requirements: restricting rule to JsVariableDeclarator (no plain assignments) and adding semantic type checking for iterable support.
Out of Scope Changes check ✅ Passed All changes directly target the useDestructuring rule fix and its test cases; no unrelated modifications detected outside the scope of issue #8480.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes.

Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the reviews.auto_title_placeholder setting.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs (1)

274-326: Consider handling union and intersection types.

The type matching is comprehensive for primitives, but TsUnionType and TsIntersectionType aren't explicitly handled. For example, string | number[] could contain an iterable variant. The current fallback to None is conservative, but you might want to refine this in future.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs` around lines
274 - 326, The matcher currently omits AnyTsType::TsUnionType and
AnyTsType::TsIntersectionType; update array_destructuring_support_for_type to
handle these by iterating their member types (for union: node.types(), for
intersection: node.types()), recursively calling
array_destructuring_support_for_type (incrementing depth and passing model) and
then combining results: return Some(true) if any member yields Some(true),
return Some(false) if no true and at least one Some(false), otherwise return
None; reuse the existing recursion pattern and depth checks used for
TsParenthesizedType/TsTypeOperatorType and calls to
array_destructuring_support_for_declaration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.ts`:
- Around line 27-35: The test has a type mismatch: variable "thing" is declared
as SomeObj but is assigned someObj.thing (a number). Fix by changing the
declaration of "thing" from type SomeObj to number (i.e., let thing: number;) so
the assignment thing = someObj.thing; is type-correct; update the declaration
near the SomeObj type and the let thing binding in this test.

---

Nitpick comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs`:
- Around line 274-326: The matcher currently omits AnyTsType::TsUnionType and
AnyTsType::TsIntersectionType; update array_destructuring_support_for_type to
handle these by iterating their member types (for union: node.types(), for
intersection: node.types()), recursively calling
array_destructuring_support_for_type (incrementing depth and passing model) and
then combining results: return Some(true) if any member yields Some(true),
return Some(false) if no true and at least one Some(false), otherwise return
None; reuse the existing recursion pattern and depth checks used for
TsParenthesizedType/TsTypeOperatorType and calls to
array_destructuring_support_for_declaration.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 516728d2-d38a-4e4f-b8e2-a1d900488f6a

📥 Commits

Reviewing files that changed from the base of the PR and between b309dde and 963b130.

⛔ Files ignored due to path filters (3)
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (5)
  • .changeset/fix-use-destructuring-illegal-cases.md
  • crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.ts
💤 Files with no reviewable changes (1)
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/invalid.js

'thing' should be declared as 'number' (the type of someObj.thing),
not 'SomeObj' (the whole object type). Caught by CodeRabbit review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

This PR introduced some sort of recursion + depth short circuit. This hasn't been tested nor documented (in the code and for our users).

I don' this the depth short circuit is needed. We hardly use it in our lint rules.

Comment on lines +181 to +184
!matches!(
array_destructuring_support_for_expression(object, model, 0),
Some(false)
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This function serves little to no value. Just use it with the try operator array_destructuring_support_for_expression()? and you're good

)
}

fn array_destructuring_support_for_expression(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please provide some docstrings that explain the business logic of the function.

Comment on lines +200 to +201
let declaration = model.binding(&reference)?.tree().declaration()?;
array_destructuring_support_for_declaration(&declaration, model, depth + 1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is plain recursion, which we try to avoid. You can achieve the same result with a simple loop

model: &SemanticModel,
depth: usize,
) -> Option<bool> {
if depth >= 8 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Case in point. What's height and why? Hence the docs

model: &SemanticModel,
depth: usize,
) -> Option<bool> {
if depth >= 8 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Magic number that we don't want

}

let declaration = model.binding(reference)?.tree().declaration()?;
return array_destructuring_support_for_declaration(&declaration, model, depth + 1);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Recursion spotted

Remove depth parameter and depth>=8 guard from recursive helpers in
use_destructuring rule as requested in PR 9457 maintainer feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Author

@Vadaski Vadaski left a comment

Choose a reason for hiding this comment

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

Thanks for the feedback, @ematipico! You're right — the depth short-circuit was unnecessary overhead. I've removed all depth parameters and guard checks from the four recursive helper functions (array_destructuring_support_for_expression, array_destructuring_support_for_declaration, array_destructuring_support_for_type_annotation, array_destructuring_support_for_type). All existing tests still pass.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs (1)

229-231: ⚠️ Potential issue | 🔴 Critical

Cyclic type aliases can blow the stack here.

A chain like type A = B; type B = A; will ping-pong between TsTypeAliasDeclaration and TsReferenceType forever. In analyser code, that is a nasty little stack-overflow trap on invalid-but-parseable input. Please add cycle detection or make the walk iterative.

Also applies to: 277-296

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs` around lines
229 - 231, The recursion from AnyJsBindingDeclaration::TsTypeAliasDeclaration
into array_destructuring_support_for_type can infinite-loop on cyclic type
aliases (e.g., A -> B -> A); add cycle detection by threading a mutable visited
set (e.g., HashSet<Id> or HashSet<String>) through
array_destructuring_support_for_type and any helpers that descend into
TsReferenceType and other type nodes, checking and early-returning when an alias
id/name is already present, and ensure all call sites (including the other spots
noted around the 277-296 range) pass this visited set; alternatively convert the
recursive walk to an explicit stack-based loop that tracks seen aliases and
stops when a cycle is detected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs`:
- Around line 180-184: The current helper treats None (unknown) as supported;
adjust array_destructuring_support_for_expression to return Some(true) for
proven-iterable, Some(false) for proven-not-iterable, and None for unknown, and
change supports_array_destructuring to only return true when
array_destructuring_support_for_expression(...) is Some(true) (i.e., do not
treat None as safe). Additionally, allow a permissive true only when the
expression's static type is explicitly the `any` type by querying the
SemanticModel (use the existing SemanticModel type-check helper you have) so
unknown expressions like foo.bar[0] or getFoo()[0] don't get suggestions unless
explicitly typed as any. Ensure the same logic is applied to the checks
implemented in the code block handled in lines 187-199.

---

Duplicate comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs`:
- Around line 229-231: The recursion from
AnyJsBindingDeclaration::TsTypeAliasDeclaration into
array_destructuring_support_for_type can infinite-loop on cyclic type aliases
(e.g., A -> B -> A); add cycle detection by threading a mutable visited set
(e.g., HashSet<Id> or HashSet<String>) through
array_destructuring_support_for_type and any helpers that descend into
TsReferenceType and other type nodes, checking and early-returning when an alias
id/name is already present, and ensure all call sites (including the other spots
noted around the 277-296 range) pass this visited set; alternatively convert the
recursive walk to an explicit stack-based loop that tracks seen aliases and
stops when a cycle is detected.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e5cbf1e4-5d87-454b-ace8-fa15bbe75a37

📥 Commits

Reviewing files that changed from the base of the PR and between 4924937 and 0687f52.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs

Comment on lines +180 to +184
fn supports_array_destructuring(object: &AnyJsExpression, model: &SemanticModel) -> bool {
!matches!(
array_destructuring_support_for_expression(object, model),
Some(false)
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

None currently means “unknown”, but it gets treated as “safe”.

Lines 180-184 accept anything except Some(false), while Lines 187-199 only prove iterability for array literals and identifiers. That means cases like foo.bar[0] or getFoo()[0] still receive an array-destructuring suggestion even though their iterability was never verified. Please split “unknown” from “supported”, or only keep the permissive path for an explicit any case.

Also applies to: 187-199

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs` around lines
180 - 184, The current helper treats None (unknown) as supported; adjust
array_destructuring_support_for_expression to return Some(true) for
proven-iterable, Some(false) for proven-not-iterable, and None for unknown, and
change supports_array_destructuring to only return true when
array_destructuring_support_for_expression(...) is Some(true) (i.e., do not
treat None as safe). Additionally, allow a permissive true only when the
expression's static type is explicitly the `any` type by querying the
SemanticModel (use the existing SemanticModel type-check helper you have) so
unknown expressions like foo.bar[0] or getFoo()[0] don't get suggestions unless
explicitly typed as any. Ensure the same logic is applied to the checks
implemented in the code block handled in lines 187-199.

…ion on cyclic type aliases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Author

@Vadaski Vadaski left a comment

Choose a reason for hiding this comment

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

Thanks @coderabbitai — you're right, removing the depth guard exposed the stack-overflow risk. Fixed by threading a HashSet<TextRange> (visited set) through all recursive helpers. Cycle detection is inserted at both recursion entry points: TsTypeAliasDeclaration and TsReferenceType. A regression test for type CyclicA = CyclicB; type CyclicB = CyclicA; is also added. Codex review: no findings.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs (1)

181-203: 🛠️ Refactor suggestion | 🟠 Major

Docstrings still missing for helper functions.

Per prior feedback, please add docstrings explaining the business logic — particularly the tri-state return semantics (Some(true) = iterable, Some(false) = not iterable, None = unknown).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs` around lines
181 - 203, Add docstrings to the helper functions to document their business
logic and the tri-state return semantics: update supports_array_destructuring
and array_destructuring_support_for_expression (and any related helper like
array_destructuring_support_for_declaration) with short comments that explain
what each function does, what inputs it expects, and that they return Some(true)
when the expression is iterable (supports array destructuring), Some(false) when
it is known to be not iterable, and None when the iterability is unknown; keep
the descriptions brief and mention any notable behavior such as omitting
parentheses and following identifier bindings via SemanticModel.
🧹 Nitpick comments (2)
crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs (2)

244-245: Catch-all returns None for 31 unhandled AnyJsBindingDeclaration variants.

This is acceptable as a starting point, but worth noting that declarations like JsCatchDeclaration, function declarations with return types, and import specifiers will fall through to permissive handling.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs` around lines
244 - 245, The catch-all arm ("_ => None") in the match over
AnyJsBindingDeclaration silently returns None for many unhandled variants;
replace the blanket fallback with explicit matches (e.g., handle
JsCatchDeclaration, function declarations with return types, import specifiers,
etc.) or at minimum enumerate the remaining AnyJsBindingDeclaration variants in
explicit arms that return None with a comment/TODO so the behavior is deliberate
and discoverable; update the match in the code that matches on
AnyJsBindingDeclaration (the block ending with "_ => None") to either implement
proper handling for those specific variants or add explicit arms with
explanatory comments.

317-318: Union and intersection types fall through to None.

For TsUnionType, you could check whether all variants are iterable (returning Some(true)) or any is definitively non-iterable (Some(false)). Not critical, but would improve precision.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs` around lines
317 - 318, The match currently falls through to None for union/intersection
types; update the type-checking function (the match that returns Option<bool>
for iterability — the arm ending with `_ => None`) to handle TsUnionType and
TsIntersectionType by iterating their variants: map each variant to the same
Option<bool> check, then for both unions and intersections return Some(false) if
any variant is Some(false), return Some(true) if all variants are Some(true),
otherwise return None; reference TsUnionType and TsIntersectionType in the new
match arms and reuse the existing per-variant check logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs`:
- Around line 181-203: Add docstrings to the helper functions to document their
business logic and the tri-state return semantics: update
supports_array_destructuring and array_destructuring_support_for_expression (and
any related helper like array_destructuring_support_for_declaration) with short
comments that explain what each function does, what inputs it expects, and that
they return Some(true) when the expression is iterable (supports array
destructuring), Some(false) when it is known to be not iterable, and None when
the iterability is unknown; keep the descriptions brief and mention any notable
behavior such as omitting parentheses and following identifier bindings via
SemanticModel.

---

Nitpick comments:
In `@crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs`:
- Around line 244-245: The catch-all arm ("_ => None") in the match over
AnyJsBindingDeclaration silently returns None for many unhandled variants;
replace the blanket fallback with explicit matches (e.g., handle
JsCatchDeclaration, function declarations with return types, import specifiers,
etc.) or at minimum enumerate the remaining AnyJsBindingDeclaration variants in
explicit arms that return None with a comment/TODO so the behavior is deliberate
and discoverable; update the match in the code that matches on
AnyJsBindingDeclaration (the block ending with "_ => None") to either implement
proper handling for those specific variants or add explicit arms with
explanatory comments.
- Around line 317-318: The match currently falls through to None for
union/intersection types; update the type-checking function (the match that
returns Option<bool> for iterability — the arm ending with `_ => None`) to
handle TsUnionType and TsIntersectionType by iterating their variants: map each
variant to the same Option<bool> check, then for both unions and intersections
return Some(false) if any variant is Some(false), return Some(true) if all
variants are Some(true), otherwise return None; reference TsUnionType and
TsIntersectionType in the new match arms and reuse the existing per-variant
check logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 066fe9c6-6f2e-4b2d-924c-aafd68de587c

📥 Commits

Reviewing files that changed from the base of the PR and between 0687f52 and 54d0d9c.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • .changeset/fix-use-destructuring-cyclic-aliases.md
  • crates/biome_js_analyze/src/lint/nursery/use_destructuring.rs
  • crates/biome_js_analyze/tests/specs/nursery/useDestructuring/valid.ts

@ematipico
Copy link
Copy Markdown
Member

Closing, i'm not satisfied by the bot

@ematipico ematipico closed this Mar 12, 2026
Copy link
Copy Markdown
Author

@Vadaski Vadaski left a comment

Choose a reason for hiding this comment

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

Thanks @coderabbitai — added /// docstrings to all five helper functions (supports_array_destructuring, array_destructuring_support_for_expression, array_destructuring_support_for_declaration, array_destructuring_support_for_type_annotation, array_destructuring_support_for_type) documenting each function's purpose and the tri-state return semantics (Some(true) = iterable, Some(false) = non-iterable, None = unknown). Codex review: no findings.

@Vadaski
Copy link
Copy Markdown
Author

Vadaski commented Mar 12, 2026

Thanks for the transparency, @ematipico. Totally understand — I've been using Biome in my own projects and wanted to give back, but I can see how the back-and-forth with automated tools made this noisy to review. I'll be more mindful of that in future contributions. Appreciate the time you spent looking at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 useDestructuring suggests illegal destructuring operations

2 participants