oxc-project/oxc · warning · OxcDiagnostic

Unexpected class with only a constructor.

Error message

Unexpected class with only a constructor.

What it means

Third diagnostic of no-extraneous-class: a class containing only a constructor is behaviourally just a function, so the rule suggests replacing it with a standalone function or deleting it (help at no_extraneous_class.rs:114-117).

Source

Thrown at crates/oxc_linter/src/rules/typescript/no_extraneous_class.rs:112

);

fn empty_class_diagnostic(span: Span, has_decorators: bool) -> OxcDiagnostic {
    let help = if has_decorators {
        r#"Set "allowWithDecorator": true in your config to allow empty decorated classes"#
    } else {
        "Delete this class"
    };
    OxcDiagnostic::warn("Unexpected empty class.").with_label(span).with_help(help)
}

fn only_static_no_extraneous_class_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected class with only static properties.")
        .with_label(span)
        .with_help("Try using standalone functions instead of static methods")
}

fn only_constructor_no_extraneous_class_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected class with only a constructor.")
        .with_label(span)
        .with_help("Try replacing this class with a standalone function or deleting it entirely")
}

impl Rule for NoExtraneousClass {
    fn from_configuration(value: serde_json::Value) -> Result<Self, serde_json::error::Error> {
        DefaultRuleConfig::<Self>::from_value(value).map(DefaultRuleConfig::into_inner)
    }

    fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
        let AstKind::Class(class) = node.kind() else {
            return;
        };
        if class.heritage.is_some() || (self.allow_with_decorator && !class.decorators.is_empty()) {
            return;
        }
        let span = class.id.as_ref().map_or(class.span, |id| id.span);
        let body = &class.body.body;

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Convert it to a factory function returning the object
  2. Add real methods or fields if the class is meant to grow
  3. Delete the class entirely if nothing depends on it

Example fix

// before
class Point {
  constructor(public x: number, public y: number) {}
}

// after
function makePoint(x: number, y: number) {
  return { x, y };
}
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --deny-warnings .

Prevention

When it happens

Trigger: `class Point { constructor(x, y) { this.x = x; this.y = y; } }` with no methods, fields, or other members - the run() logic reports classes whose only member is the constructor.

Common situations: DTO or value-holder classes before real fields were added, generated stubs, refactoring leftovers where methods were moved out.

Related errors


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