Repository: oxc-project/oxc
Pull request #9993: refactor(linter): add fixer for `typescript-eslint/no-non-null-asserted-optional-chain`
Author: login: camchenry
Labels: name: A-linter
description: Area - Linter
name: C-cleanup
description: Category -  technical debt or refactoring. Solution not expected to change behavior
name: A-editor
description: Area - Editor and Language Server
Created: 2025-03-23T19:18:03Z | Merged: 2025-03-24T02:57:24Z

Adds fixes for the `typescript-eslint/no-non-null-asserted-optional-chain` rule in the linter and adds better diagnostic messages with labeled spans.


Diff:
diff --git a/crates/oxc_language_server/src/linter/snapshots/fixtures_linter_issue_9958_issue.ts.snap b/crates/oxc_language_server/src/linter/snapshots/fixtures_linter_issue_9958_issue.ts.snap
index 3650af5e16f2d..1890a9cb181af 100644
--- a/crates/oxc_language_server/src/linter/snapshots/fixtures_linter_issue_9958_issue.ts.snap
+++ b/crates/oxc_language_server/src/linter/snapshots/fixtures_linter_issue_9958_issue.ts.snap
@@ -15,14 +15,26 @@ tags: None
 
 code: "typescript-eslint(no-non-null-asserted-optional-chain)"
 code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/typescript_eslint/no-non-null-asserted-optional-chain"
-message: "non-null assertions after an optional chain expression\nhelp: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion."
-range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 18 } }
-related_information[0].message: ""
+message: "Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.\nhelp: Remove the non-null assertion."
+range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
+related_information[0].message: "non-null assertion made after optional chain"
 related_information[0].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
-related_information[0].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 18 } }
-related_information[1].message: ""
+related_information[0].location.range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 22 } }
+related_information[1].message: "optional chain used"
 related_information[1].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
-related_information[1].location.range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 21 } }
+related_information[1].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
 severity: Some(Error)
 source: Some("oxc")
 tags: None
+            
+
+code: "None"
+code_description.href: "None"
+message: "non-null assertion made after optional chain"
+range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 22 } }
+related_information[0].message: "original diagnostic"
+related_information[0].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
+related_information[0].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
+severity: Some(Hint)
+source: Some("oxc")
+tags: None
diff --git a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs
index f17663d432956..25d0265684779 100644
--- a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs
+++ b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs
@@ -12,10 +12,14 @@ use crate::{
     rule::Rule,
 };
 
-fn no_non_null_asserted_optional_chain_diagnostic(span: Span, span1: Span) -> OxcDiagnostic {
-    OxcDiagnostic::warn("non-null assertions after an optional chain expression")
-        .with_help("Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.")
-        .with_labels([span, span1])
+fn no_non_null_asserted_optional_chain_diagnostic(
+    chain_span: Span,
+    assertion_span: Span,
+) -> OxcDiagnostic {
+    OxcDiagnostic::warn("Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.")
+        .with_help("Remove the non-null assertion.")
+        .with_label(assertion_span.primary_label("non-null assertion made after optional chain"))
+        .and_label(chain_span.label("optional chain used"))
 }
 
 #[derive(Debug, Default, Clone)]
@@ -27,20 +31,35 @@ declare_oxc_lint!(
     /// Disallow non-null assertions after an optional chain expression.
     ///
     /// ### Why is this bad?
-    /// `?.` optional chain expressions provide undefined if an object is null or undefined.
-    /// Using a `!` non-null assertion to assert the result of an `?.` optional chain expression is non-nullable is likely wrong.
     ///
-    /// Most of the time, either the object was not nullable and did not need the `?.` for its property lookup, or the `!` is incorrect and introducing a type safety hole.
+    /// By design, optional chain expressions (`?.`) provide `undefined` as the expression's value, if the object being
+    /// accessed is `null` or `undefined`, instead of throwing an error. Using a non-null assertion (`!`) to assert the
+    /// result of an optional chain expression is contradictory and likely wrong, as it indicates the code is both expecting
+    /// the value to be potentially `null` or `undefined` and non-null at the same time.
+    ///
+    /// In most cases, either:
+    /// 1. The object is not nullable and did not need the `?.` for its property lookup
+    /// 2. The non-null assertion is incorrect and introduces a type safety hole.
+    ///
+    /// ### Examples
+    ///
+    /// Examples of **incorrect** code for this rule:
     ///
-    /// ### Example
     /// ```ts
     /// foo?.bar!;
     /// foo?.bar()!;
     /// ```
+    ///
+    /// Examples of **correct** code for this rule:
+    ///
+    /// ```ts
+    /// foo?.bar;
+    /// foo.bar!;
+    /// ```
     NoNonNullAssertedOptionalChain,
     typescript,
     correctness,
-    pending
+    fix
 );
 
 impl Rule for NoNonNullAssertedOptionalChain {
@@ -90,10 +109,14 @@ impl Rule for NoNonNullAssertedOptionalChain {
         if let Some(chain_span) = chain_span {
             let chain_span_end = chain_span.end;
             let non_null_end = non_null_expr.span.end - 1;
-            ctx.diagnostic(no_non_null_asserted_optional_chain_diagnostic(
-                Span::new(chain_span_end, chain_span_end),
-                Span::new(non_null_end, non_null_end),
-            ));
+            let diagnostic = no_non_null_asserted_optional_chain_diagnostic(
+                Span::sized(chain_span_end, 1),
+                Span::sized(non_null_end, 1),
+            );
+            // ctx.diagnostic(diagnostic);
+            ctx.diagnostic_with_fix(diagnostic, |fixer| {
+                fixer.delete_range(Span::sized(non_null_end, 1))
+            });
         }
     }
 
@@ -143,11 +166,24 @@ fn test() {
         "(foo?.bar!)()",
     ];
 
+    let fix = vec![
+        ("foo?.bar!", "foo?.bar"),
+        ("foo?.['bar']!", "foo?.['bar']"),
+        ("foo?.bar()!", "foo?.bar()"),
+        ("(foo?.bar)!.baz", "(foo?.bar).baz"),
+        ("(foo?.bar)!().baz", "(foo?.bar)().baz"),
+        ("(foo?.bar)!", "(foo?.bar)"),
+        ("(foo?.bar)!()", "(foo?.bar)()"),
+        ("(foo?.bar!)", "(foo?.bar)"),
+        ("(foo?.bar!)()", "(foo?.bar)()"),
+    ];
+
     Tester::new(
         NoNonNullAssertedOptionalChain::NAME,
         NoNonNullAssertedOptionalChain::PLUGIN,
         pass,
         fail,
     )
+    .expect_fix(fix)
     .test_and_snapshot();
 }
diff --git a/crates/oxc_linter/src/snapshots/typescript_no_non_null_asserted_optional_chain.snap b/crates/oxc_linter/src/snapshots/typescript_no_non_null_asserted_optional_chain.snap
index 9150d29f6161e..8d2ce344fa15d 100644
--- a/crates/oxc_linter/src/snapshots/typescript_no_non_null_asserted_optional_chain.snap
+++ b/crates/oxc_linter/src/snapshots/typescript_no_non_null_asserted_optional_chain.snap
@@ -1,72 +1,92 @@
 ---
 source: crates/oxc_linter/src/tester.rs
 ---
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:4]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:9]
  1 │ foo?.bar!;
-   ·    ▲    ▲
+   ·    ┬    ┬
+   ·    │    ╰── non-null assertion made after optional chain
+   ·    ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:4]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:13]
  1 │ foo?.['bar']!;
-   ·    ▲        ▲
+   ·    ┬        ┬
+   ·    │        ╰── non-null assertion made after optional chain
+   ·    ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:4]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:11]
  1 │ foo?.bar()!;
-   ·    ▲      ▲
+   ·    ┬      ┬
+   ·    │      ╰── non-null assertion made after optional chain
+   ·    ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:8]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:12]
  1 │ foo.bar?.()!;
-   ·        ▲   ▲
+   ·        ┬   ┬
+   ·        │   ╰── non-null assertion made after optional chain
+   ·        ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:5]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:11]
  1 │ (foo?.bar)!.baz
-   ·     ▲     ▲
+   ·     ┬     ┬
+   ·     │     ╰── non-null assertion made after optional chain
+   ·     ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:5]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:11]
  1 │ (foo?.bar)!().baz
-   ·     ▲     ▲
+   ·     ┬     ┬
+   ·     │     ╰── non-null assertion made after optional chain
+   ·     ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:5]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:11]
  1 │ (foo?.bar)!
-   ·     ▲     ▲
+   ·     ┬     ┬
+   ·     │     ╰── non-null assertion made after optional chain
+   ·     ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:5]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:11]
  1 │ (foo?.bar)!()
-   ·     ▲     ▲
+   ·     ┬     ┬
+   ·     │     ╰── non-null assertion made after optional chain
+   ·     ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:5]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:10]
  1 │ (foo?.bar!)
-   ·     ▲    ▲
+   ·     ┬    ┬
+   ·     │    ╰── non-null assertion made after optional chain
+   ·     ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.
 
-  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): non-null assertions after an optional chain expression
-   ╭─[no_non_null_asserted_optional_chain.tsx:1:5]
+  ⚠ typescript-eslint(no-non-null-asserted-optional-chain): Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.
+   ╭─[no_non_null_asserted_optional_chain.tsx:1:10]
  1 │ (foo?.bar!)()
-   ·     ▲    ▲
+   ·     ┬    ┬
+   ·     │    ╰── non-null assertion made after optional chain
+   ·     ╰── optional chain used
    ╰────
-  help: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion.
+  help: Remove the non-null assertion.


Reviews:
user: login: shulaoda
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T00:55:53Z
user: login: shulaoda
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T00:55:58Z
user: login: camchenry
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T02:18:04Z

Review comments:
diff_hunk: @@ -15,14 +15,26 @@ tags: None
 
 code: "typescript-eslint(no-non-null-asserted-optional-chain)"
 code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/typescript_eslint/no-non-null-asserted-optional-chain"
-message: "non-null assertions after an optional chain expression\nhelp: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion."
-range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 18 } }
-related_information[0].message: ""
+message: "Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.\nhelp: Remove the non-null assertion."
+range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
+related_information[0].message: "non-null assertion made after optional chain"
 related_information[0].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
-related_information[0].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 18 } }
-related_information[1].message: ""
+related_information[0].location.range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 22 } }
+related_information[1].message: "optional chain used"
 related_information[1].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
-related_information[1].location.range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 21 } }
+related_information[1].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
 severity: Some(Error)
 source: Some("oxc")
 tags: None
+            
+
+code: "None"
+code_description.href: "None"
+message: "non-null assertion made after optional chain"
+range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 22 } }
path: crates/oxc_language_server/src/linter/snapshots/fixtures_linter_issue_9958_issue.ts.snap
user: login: shulaoda
body: Why did this change introduce the new snapshot?
created_at: 2025-03-24T00:55:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -15,14 +15,26 @@ tags: None
 
 code: "typescript-eslint(no-non-null-asserted-optional-chain)"
 code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/typescript_eslint/no-non-null-asserted-optional-chain"
-message: "non-null assertions after an optional chain expression\nhelp: Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong. You should remove the non-null assertion."
-range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 18 } }
-related_information[0].message: ""
+message: "Optional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.\nhelp: Remove the non-null assertion."
+range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
+related_information[0].message: "non-null assertion made after optional chain"
 related_information[0].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
-related_information[0].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 18 } }
-related_information[1].message: ""
+related_information[0].location.range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 22 } }
+related_information[1].message: "optional chain used"
 related_information[1].location.uri: "file://<variable>/fixtures/linter/issue_9958/issue.ts"
-related_information[1].location.range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 21 } }
+related_information[1].location.range: Range { start: Position { line: 11, character: 18 }, end: Position { line: 11, character: 19 } }
 severity: Some(Error)
 source: Some("oxc")
 tags: None
+            
+
+code: "None"
+code_description.href: "None"
+message: "non-null assertion made after optional chain"
+range: Range { start: Position { line: 11, character: 21 }, end: Position { line: 11, character: 22 } }
path: crates/oxc_language_server/src/linter/snapshots/fixtures_linter_issue_9958_issue.ts.snap
user: login: camchenry
body: It's related to the previous PR: when a diagnostic has multiple spans associated, we don't produce additional diagnostics unless the message content is non-empty. VS Code integration seemed to not work when the message content was empty. But now that I've added labels for these spans, we are able to report these diagnostics again, much like we do in the CLI.
created_at: 2025-03-24T02:18:04Z
author_association: MEMBER

PR comments:
user: login: camchenry
created_at: 2025-03-23T19:18:19Z
body: * **#9993** <a href="https://app.graphite.dev/github/pr/oxc-project/oxc/9993?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a> 👈 <a href="https://app.graphite.dev/github/pr/oxc-project/oxc/9993?utm_source=stack-comment-view-in-graphite" target="_blank">(View in Graphite)</a>
* **#9991** <a href="https://app.graphite.dev/github/pr/oxc-project/oxc/9991?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a>
* `main`
<hr />

## How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:
- <kbd>0-merge</kbd> - adds this PR to the back of the merge queue
- <kbd>hotfix</kbd> - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using [this link](https://app.graphite.dev/invite/github/oxc-project?ref=merge-queue-instructions-in-stack-comment&prId=9993).

<h2></h2>
<sub>

An organization admin has enabled the [Graphite Merge Queue](https://graphite.dev/docs/graphite-merge-queue) in this repository.

</sub>

<sub>

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

</sub>

<h2></h2>

This stack of pull requests is managed by <a href="https://graphite.dev?utm-source=stack-comment"><b>Graphite</b></a>. Learn more about <a href="https://stacking.dev/?utm_source=stack-comment">stacking</a>.
<!-- Current dependencies on/for this PR: -->
author_association: MEMBER
user: login: codspeed-hq[bot]
created_at: 2025-03-23T19:24:59Z
body: <!-- __CODSPEED_PERFORMANCE_REPORT_COMMENT__ -->
<!-- __CODSPEED_INSTRUMENTATION_PERFORMANCE_REPORT_COMMENT__ -->

## [CodSpeed Instrumentation Performance Report](https://codspeed.io/oxc-project/oxc/branches/03-23-refactor_linter_add_fixer_for_typescript-eslint_no-non-null-asserted-optional-chain_)

### Merging #9993 will **not alter performance**

<sub>Comparing <code>03-23-refactor_linter_add_fixer_for_typescript-eslint_no-non-null-asserted-optional-chain_</code> (ad06194) with <code>main</code> (2d7b0cf)</sub>



### Summary

`✅ 33` untouched benchmarks  




author_association: NONE
user: login: camchenry
created_at: 2025-03-24T02:19:46Z
body: ### Merge activity

* **Mar 23, 10:19 PM EDT**: The merge label '0-merge' was detected. This PR will be added to the [Graphite merge queue](https://app.graphite.dev/merges?org=oxc-project&repo=oxc) once it meets the requirements.
* **Mar 23, 10:51 PM EDT**: A user added this pull request to the [Graphite merge queue](https://app.graphite.dev/merges?org=oxc-project&repo=oxc).
* **Mar 23, 10:57 PM EDT**: A user  merged this pull request with the [Graphite merge queue](https://app.graphite.dev/merges?org=oxc-project&repo=oxc).

author_association: MEMBER