{"record":{"id":"d02e851590299494","repo":"oxc-project/oxc","slug":"interfaces-cannot-be-constructed-only-classes","errorCode":null,"errorMessage":"Interfaces cannot be constructed, only classes.","messagePattern":"Interfaces cannot be constructed, only classes\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/typescript/no_misused_new.rs","lineNumber":15,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{\n        ClassElement, IdentifierReference, PropertyKey, TSSignature, TSType, TSTypeAnnotation,\n        TSTypeName,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn no_misused_new_interface_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Interfaces cannot be constructed, only classes.\")\n        .with_help(\"Consider removing this method from your interface.\")\n        .with_label(span)\n}\n\nfn no_misused_new_class_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Class cannot have method named `new`.\")\n        .with_help(\"This method name is confusing, consider renaming the method to `constructor`\")\n        .with_label(span)\n}\n\nfn get_return_type_identifier<'a, 'b>(\n    return_type: Option<&'b TSTypeAnnotation<'a>>,\n) -> Option<&'b IdentifierReference<'a>> {\n    if let Some(return_type) = return_type\n        && let TSType::TSTypeReference(type_ref) = &return_type.type_annotation\n        && let TSTypeName::IdentifierReference(id) = &type_ref.type_name\n    {\n        Some(id)","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/typescript/no_misused_new.rs#L1-L33","documentation":"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.","triggerScenarios":"`interface Square { new (size: number): Square; area(): number; }` - the `new` member returns the interface itself.","commonSituations":"Patterns copied from C# where interfaces carry constructor-ish contracts, writing DI factories, misunderstanding TS construct signatures.","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"],"exampleFix":"// before\ninterface Square {\n  new (size: number): Square;\n  area(): number;\n}\n\n// after\nclass Square {\n  constructor(readonly size: number) {}\n  area() { return this.size ** 2; }\n}","handlingStrategy":"validation","validationCode":"npx oxlint --deny-warnings .","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["typescript","lint","interface","constructor","design"],"backgroundTag":"misused-new","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}