oxc-project/oxc · warning · OxcDiagnostic
Do not use useless `undefined`.
Error message
Do not use useless `undefined`.
What it means
Diagnostic from the oxlint rule `unicorn/no-useless-undefined` (pedantic, autofixable). It fires where `undefined` is the implicit default anyway: `return undefined;`, `yield undefined;`, an arrow's concise body `() => undefined`, `let`/`var` initialization `let foo = undefined;`, destructuring defaults `const {foo = undefined} = {}`, parameter defaults `function f(bar = undefined) {}`, and trailing `undefined` call arguments `foo(bar, undefined)`. Exceptions: TypeScript functions with an explicit return type, `const` declarations, `yield* undefined`, parameter defaults after an optional parameter, and calls to a large ignore list (`toEqual`, `toBe`, `toHaveBeenCalledWith`, `push`, `set*` names, `createContext`, `ref`, `bind`, etc.) where `undefined` is a meaningful argument.
Source
Thrown at crates/oxc_linter/src/rules/unicorn/no_useless_undefined.rs:19
use oxc_ast::{
AstKind,
ast::{Argument, CallExpression, Expression, VariableDeclarationKind},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
AstNode,
ast_util::{is_method_call, outermost_paren_parent},
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
fn warn() -> OxcDiagnostic {
OxcDiagnostic::warn("Do not use useless `undefined`.")
.with_help("Consider removing `undefined` or using `null` instead.")
}
fn no_useless_undefined_diagnostic(span: Span) -> OxcDiagnostic {
warn().with_label(span)
}
fn no_useless_undefined_diagnostic_spans(spans: Vec<Span>) -> OxcDiagnostic {
warn().with_labels(spans)
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoUselessUndefined {
/// Whether to check for useless `undefined` in function call arguments.
check_arguments: bool,
/// Whether to check for useless `undefined` in arrow function bodies.
check_arrow_function_body: bool,View on GitHub (pinned to e1e7af627c)
Solutions
- Remove the `undefined`: `let foo = undefined;` -> `let foo;`, `() => undefined` -> `() => {}`, `return undefined;` -> `return;`.
- Run `oxlint --fix` to apply the rule's autofixes.
- If you need an explicit 'no value' sentinel, use `null` instead, as the help suggests.
- Configure the rule: `{ "checkArguments": false }` for calls like `run(undefined)` against optional parameters, `{ "checkArrowFunctionBody": false }` for arrow bodies.
- For TypeScript, adding an explicit return type annotation (e.g. `(): undefined`) exempts the function.
Example fix
// before
let foo = undefined;
const noop = () => undefined;
function f(bar = undefined) {}
// after
let foo;
const noop = () => {};
function f(bar) {} Defensive patterns
Strategy: validation
Validate before calling
# detect likely-useless undefined usages rg -n --type js '(?:return|yield)\s+undefined\s*;|=>\s*undefined\s*;|(?:let|var)\s+\w+\s*=\s*undefined|=\s*undefined\s*[,}]|,\s*undefined\s*[,)]' src/
Prevention
- Rely on implicit defaults: bare `return;`, `let x;`, `function f(a) {}`.
- Use `null` when an explicit sentinel value is required; reserve `undefined` for genuine values (test matchers, `createContext`, `ref`).
- Configure `checkArguments: false` if your API relies on optional-parameter calls with `undefined`.
- Set `allowImplicit` on eslint array-callback-return/getter-return when running both linters.
When it happens
Trigger: `function foo() { return undefined; }`, `function* f() { yield undefined; }`, `const noop = () => undefined;`, `let a = undefined;`, `const {foo = undefined} = {};`, `function foo([bar = undefined] = []) {}`, `foo(bar, undefined, undefined);` (only the trailing run is removed). Options `checkArguments` and `checkArrowFunctionBody` (both default `true`) disable the argument and arrow-body checks respectively.
Common situations: Verbose code from developers who want explicitness about returning nothing, and refactors from APIs where `undefined` was a real value. Conflicts with `eslint/array-callback-return` and `getter-return` unless `allowImplicit` is set; test frameworks like Jest/Vue (`toEqual(undefined)`, `ref(undefined)`) are pre-exempted via the ignore list.
Related errors
- Useless case in switch statement.
- IIFE with parenthesized arrow function body is considered un
- The {expr_type} is useless
- Empty fallbacks in spreads are unnecessary
- encountered allocation error
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/0f4e547daa27cedb.
Report an issue: GitHub.