oxc-project/oxc · warning · OxcDiagnostic

Unexpected empty class.

Error message

Unexpected empty class.

What it means

First diagnostic of oxlint's no-extraneous-class: a class declaration with no body members is flagged as 'Unexpected empty class.' because such classes typically act as namespace or marker placeholders. When the class carries decorators, the help at no_extraneous_class.rs:104-108 instead points to the allowWithDecorator config option.

Source

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

    /// const version = 42;
    /// const isProduction = () => process.env.NODE_ENV === 'production';
    /// ```
    NoExtraneousClass,
    typescript,
    suspicious,
    dangerous_suggestion,
    config = NoExtraneousClass,
    version = "0.7.0",
    short_description = "Disallow classes used as namespaces.",
);

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)
    }

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Delete the class if nothing uses it
  2. Add the members it is meant to hold
  3. For decorator-anchored empty classes, set allowWithDecorator: true in the rule config
  4. Suppress inline with an oxlint-disable comment when intentional

Example fix

// before
class ApiError {}

// after
class ApiError extends Error {
  constructor(message: string) {
    super(message);
  }
}
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --deny-warnings .

# decorator-heavy codebase:
{
  "rules": { "typescript/no-extraneous-class": ["error", { "allowWithDecorator": true }] }
}

Prevention

When it happens

Trigger: `class Foo {}` with an empty body; an empty class annotated with decorators (for example an Angular or NestJS anchor class) while allowWithDecorator is false (the default).

Common situations: Decorator-based frameworks that need empty classes as anchors, scaffolding leftovers, classes kept 'for later' that never gained members.

Related errors


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