oxc-project/oxc · warning · OxcDiagnostic
Interfaces cannot be constructed, only classes.
Error message
Interfaces cannot be constructed, only classes.
What it means
Oxlint's port of typescript-eslint's no-misused-new. Developers sometimes write a member `new(): Foo` inside `interface Foo` believing it declares a constructor, but interfaces cannot be constructed; only classes can. The rule detects an interface member named `new` whose return type resolves to the interface's own identifier (via get_return_type_identifier at no_misused_new.rs:26-34) and flags it.
Source
Thrown at crates/oxc_linter/src/rules/typescript/no_misused_new.rs:15
use oxc_ast::{
AstKind,
ast::{
ClassElement, IdentifierReference, PropertyKey, TSSignature, TSType, TSTypeAnnotation,
TSTypeName,
},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};
fn no_misused_new_interface_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Interfaces cannot be constructed, only classes.")
.with_help("Consider removing this method from your interface.")
.with_label(span)
}
fn no_misused_new_class_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Class cannot have method named `new`.")
.with_help("This method name is confusing, consider renaming the method to `constructor`")
.with_label(span)
}
fn get_return_type_identifier<'a, 'b>(
return_type: Option<&'b TSTypeAnnotation<'a>>,
) -> Option<&'b IdentifierReference<'a>> {
if let Some(return_type) = return_type
&& let TSType::TSTypeReference(type_ref) = &return_type.type_annotation
&& let TSTypeName::IdentifierReference(id) = &type_ref.type_name
{
Some(id)View on GitHub (pinned to e1e7af627c)
Solutions
- Remove the `new` member from the interface
- Provide a class (or a separate factory function) for construction
- If a construct signature is truly needed, have it return a different type (typically a class), not the interface itself
Example fix
// before
interface Square {
new (size: number): Square;
area(): number;
}
// after
class Square {
constructor(readonly size: number) {}
area() { return this.size ** 2; }
} Defensive patterns
Strategy: validation
Validate before calling
npx oxlint --deny-warnings .
Prevention
- Remember interfaces describe shapes; construction belongs to classes or factory functions
- Review copied C#-style interface contracts for `new` members before committing
- When you need construct signatures, return a class type, not the interface itself
When it happens
Trigger: `interface Square { new (size: number): Square; area(): number; }` - the `new` member returns the interface itself.
Common situations: Patterns copied from C# where interfaces carry constructor-ish contracts, writing DI factories, misunderstanding TS construct signatures.
Related errors
- The generic type arguments should be specified as part of th
- The generic type arguments should be specified as part of th
- Use a property signature instead of a method signature.
- Use a method signature instead of a property signature.
- an empty interface is equivalent to `{}`
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/d02e851590299494.
Report an issue: GitHub.