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
- Convert it to a factory function returning the object
- Add real methods or fields if the class is meant to grow
- 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
- Prefer factory functions for pure data holders
- When scaffolding a class, add its first real member in the same commit
- Watch refactors that strip methods: a constructor-only class is the usual residue
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
- Unexpected class with only static properties.
- Unexpected return statement in constructor.
- Empty constructors are unnecessary
- Redundant super call in constructor
- Literals should be exposed using readonly fields.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/a2a3a7c11ee9d3a3.
Report an issue: GitHub.