oxc-project/oxc · warning · OxcDiagnostic

Unexpected class with only static properties.

Error message

Unexpected class with only static properties.

What it means

Second diagnostic of no-extraneous-class: a class whose every member is static is a namespace in disguise, so the rule flags it. The help at no_extraneous_class.rs:108-111 recommends standalone functions instead of static methods.

Source

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

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

    fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
        let AstKind::Class(class) = node.kind() else {
            return;

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Export plain functions from the module instead
  2. Replace the class with a frozen object literal or a TS namespace
  3. Add an instance member if the class genuinely models state
  4. Disable inline when the grouping is deliberate

Example fix

// before
class Str {
  static trim(s: string) { return s.trim(); }
}
const t = Str.trim(x);

// after
export function trim(s: string) { return s.trim(); }
const t = trim(x);
Defensive patterns

Strategy: validation

Validate before calling

npx oxlint --deny-warnings .

Prevention

When it happens

Trigger: `class MathUtils { static add(...) {} static sub(...) {} }` - every class element is a static member with no instance state.

Common situations: Utility bags written out of Java or C# habit, helpers grouped into a class purely for namespacing or editor discoverability.

Related errors


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