oxc-project/oxc · warning · OxcDiagnostic

Redundant super call in constructor

Error message

Redundant super call in constructor

What it means

Diagnostic from `no-useless-constructor` (redundant-super variant). A derived-class constructor does nothing but forward its exact arguments to `super(...)`, e.g. `constructor(...args) { super(...args); }` or `constructor(a, b) { super(a, b); }`. Omitting the constructor produces the same behavior through the implicit derived constructor, so the declaration is redundant. Oxc emits two labels (constructor primary, super call secondary) plus a note explaining subclass constructors default to the superclass one.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_useless_constructor.rs:32

/// ```js
/// class A { constructor(){} }
/// ```
fn no_empty_constructor(constructor_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Empty constructors are unnecessary")
        .with_label(constructor_span)
        .with_help("Remove the constructor or add code to it.")
}

/// ```js
/// class A { }
/// class B extends A {
///     constructor() {
///         super();
///     }
/// }
/// ```
fn no_redundant_super_call(constructor_span: Span, super_span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Redundant super call in constructor")
        .with_labels([
            constructor_span.primary_label("This constructor is unnecessary,"),
            super_span.label("because it only passes arguments through to the superclass"),
        ])
        .with_note("Subclasses automatically use the constructor of their superclass, making this redundant.")
        .with_help("Remove this constructor or add code to it.")
}

#[derive(Debug, Default, Clone)]
pub struct NoUselessConstructor;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow constructors that can be safely removed without changing how the class works.
    ///
    /// ### Why is this bad?
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Remove the whole constructor; the implicit derived constructor forwards identically.
  2. If other logic was planned, add it to the body so the constructor is no longer pass-through.
  3. For React class components, drop the constructor and use class property state instead.
  4. Run `oxlint --fix` to remove it automatically.

Example fix

// before
class B extends A {
  constructor(a, b) {
    super(a, b);
  }
}

// after
class B extends A {}
Defensive patterns

Strategy: validation

Validate before calling

function isPassThroughConstructor(ctor) {
  return ctor && ctor.body.length === 1 && /super\(/.test(ctor.body[0]) &&
    ctor.params.every((p, i) => ctor.body[0].arguments[i]?.name === (p.name ?? p.rest));
}

Prevention

When it happens

Trigger: `class B extends A { constructor(...args) { super(...args); } }` where parameter names/order match the super arguments exactly; also the classic `constructor() { super(); }` with no args. Fires when the constructor body consists solely of the pass-through super call.

Common situations: IDE-generated override stubs; refactors that removed logic from a forwarding constructor; Angular/React class components copied from templates that always emit `constructor(props) { super(props); }` where nothing else uses props.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/57fdc7bea0c561d8. Report an issue: GitHub.