Skip to content

fix(linter): catch missing return type on exported arrow/function expressions#19587

Merged
camc314 merged 2 commits intooxc-project:mainfrom
wagenet:worktree-explicit-module-boundary-types-fix
Feb 21, 2026
Merged

fix(linter): catch missing return type on exported arrow/function expressions#19587
camc314 merged 2 commits intooxc-project:mainfrom
wagenet:worktree-explicit-module-boundary-types-fix

Conversation

@wagenet
Copy link
Contributor

@wagenet wagenet commented Feb 20, 2026

Summary

  • run_on_exported_expression_inner called walk::walk_arrow_function_expression (the raw walk function) instead of checker.visit_arrow_function_expression. The raw walk visits AST children but bypasses ExplicitTypesChecker::visit_arrow_function_expression, which is the method that calls check_arrow_without_return. Block-body arrow functions with no inner function expressions produced no diagnostic.
  • Added symmetric fix for FunctionExpression: export default (function() { ... }) was silently ignored by the _ arm.

Incorrect behavior before fix

// Not flagged by oxlint, but should be
export default ({
    connectorTypeEnumCase,
    connectorFriendlyName,
}: {
    connectorTypeEnumCase: string;
    connectorFriendlyName: string;
}) => {
    return `${connectorTypeEnumCase}`;
};

Snapshot correction

export default () => (true ? () => {} : (): void => {}) now points to the outer exported arrow (the module boundary) instead of the inner () => {}.

Test plan

  • Existing explicit_module_boundary_types tests all pass
  • New fail test: destructured-param arrow with block body
  • New fail test: export default (function() { ... })

🤖 Generated with Claude Code

…ressions in export default

`run_on_exported_expression_inner` was calling `walk::walk_arrow_function_expression` directly, which visits children but bypasses `ExplicitTypesChecker::visit_arrow_function_expression` — the method responsible for invoking `check_arrow_without_return`. Block-body arrow functions with no inner function expressions produced no diagnostic.

Fix: call `checker.visit_arrow_function_expression(arrow)` instead. Also add symmetric handling for `FunctionExpression` (`export default (function() { ... })`), which was silently ignored by the `_` arm.

The snapshot correction for `export default () => (true ? () => {} : (): void => {})` is a side-effect improvement: the diagnostic now points to the outer exported arrow (the module boundary) rather than the inner `() => {}`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 20, 2026 19:55
@wagenet wagenet requested a review from camc314 as a code owner February 20, 2026 19:55
@github-actions github-actions bot added A-linter Area - Linter C-bug Category - Bug labels Feb 20, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes typescript-eslint/explicit-module-boundary-types in oxc_linter so exported arrow/function expressions are checked via ExplicitTypesChecker’s visit_* methods (instead of raw AST walking), restoring diagnostics that were previously skipped or incorrectly attributed to inner functions.

Changes:

  • Route exported ArrowFunctionExpression handling through checker.visit_arrow_function_expression so check_arrow_without_return runs.
  • Add symmetric handling for exported FunctionExpression via checker.visit_function.
  • Update snapshots and extend the rule’s test cases to cover the newly-detected failures and corrected label spans.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
crates/oxc_linter/src/rules/typescript/explicit_module_boundary_types.rs Fix exported expression handling to use checker visitors (arrow + function expressions) and add regression tests.
crates/oxc_linter/src/snapshots/typescript_explicit_module_boundary_types.snap Update expected diagnostics: correct span for exported conditional-arrow case; add snapshots for new failing cases.

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 20, 2026

Merging this PR will not alter performance

✅ 47 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing wagenet:worktree-explicit-module-boundary-types-fix (55ac140) with main (024f51c)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Contributor

@camc314 camc314 left a comment

Choose a reason for hiding this comment

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

thank you!

@camc314 camc314 self-assigned this Feb 21, 2026
@camc314 camc314 merged commit e38115e into oxc-project:main Feb 21, 2026
29 checks passed
camc314 pushed a commit that referenced this pull request Feb 23, 2026
# Oxlint
### 🚀 Features

- 46177dd linter: Implement unicorn/prefer-module (#19603) (camc314)
- 42f78bb linter: Implement unicorn/prefer-ternary (#19605) (camc314)

### 🐛 Bug Fixes

- 43df857 react/exhaustive-deps: Normalize .current callback deps
(#19610) (camc314)
- 574f48f linter/no-throw-literal: Close warning block (#19612)
(camc314)
- 79fe3b4 linter/prefer-mock-return-shorthand: Avoid unsafe autofixes
for call-like returns (#19581) (camc314)
- 85045e8 linter: Check protected members in
explicit-module-boundary-types (#19594) (camc314)
- e38115e linter: Catch missing return type on exported arrow/function
expressions (#19587) (Peter Wagenet)
- 419d3fd linter: Fix false negatives in typescript/no-require-imports
(#19589) (Peter Wagenet)
- 7958b56 linter: Fix syntax error reporting in some output formatters.
(#19590) (connorshea)
- 024f51c linter: Add help text to more eslint diagnostics (#19591)
(Anthony Amaro)
- a8489a1 linter: Warning `eslint/no-throw-literal` rule to be
deprecated, better use `typescript/only-throw-error` (#19593) (Said
Atrahouch)
- 50fc70d linter/type-aware: Use correct span for disable directives
(#19576) (camc314)
- 421a99c linter: Add help guidance to eslint diagnostic messages
(#19562) (Anthony Amaro)
- e81364a linter: Add help text to eslint rule diagnostics (#19560)
(Anthony Amaro)
- 89b58d0 linter: Add help text to more eslint rule diagnostics (#19561)
(Anthony Amaro)
- 74f7833 linter/jest/prefer-mock-return-shorthand: Preserve typed arrow
returns (#19556) (camc314)
- bdd6f34 linter: Restrict prefer-import-in-mock to mock calls (#19555)
(camc314)

### 📚 Documentation

- a331993 linter: Improve docs for `eslint/radix` rule. (#19611)
(connorshea)

### 🛡️ Security

- c67f9dc linter: Update ajv version. (#19613) (connorshea)
# Oxfmt
### 🚀 Features

- 984dc07 oxfmt: Strip `"experimental"SortXxx` prefix (#19567)
(leaysgur)

### 🐛 Bug Fixes

- d7b63a4 oxfmt: Update API types for `sortPackageJsonOptions` (#19569)
(leaysgur)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants