oxc-project/oxc · warning · OxcDiagnostic

an interface declaring no members is equivalent to its…

Error message

an interface declaring no members is equivalent to its supertype

What it means

Extend variant of typescript/no-empty-interface: an interface whose body is empty but which has an extends clause. It is reported as equivalent to its supertype — the declaration adds nothing and can be replaced by using the extended type directly. By default allowSingleExtends is false, so even a single-extends empty interface is reported; with allowSingleExtends true, interfaces extending exactly one type are allowed (multiple extends are always reported, since that pattern is the idiomatic union-substitute).

Solutions

  1. Use the extended type directly at the usage sites and delete the empty interface
  2. Add members so the interface actually refines its supertype
  3. If single-extend naming aliases are a deliberate pattern in the codebase, set "allowSingleExtends": true in .oxlintrc.json

Example fix

// before
interface Props extends BaseProps {}

// after
// delete Props and use BaseProps directly:
function Widget(props: BaseProps) { ... }
// or give it real members:
interface Props extends BaseProps {
  compact: boolean;
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json — allow the single-extend naming pattern if the team uses it
{
  "rules": {
    "typescript/no-empty-interface": ["warn", { "allowSingleExtends": true }]
  }
}

Prevention

When it happens

Trigger: `interface Foo extends Bar {}` with allowSingleExtends unset/false, or `interface Foo extends Bar, Baz {}` regardless of the option; the rule checks interface.extends.len() == 1 && !allow_single_extends for the single case.

Common situations: Placeholder interfaces created to be extended later; workarounds copying an external type under a local name; migration code where members were removed; teams that intentionally use single-extends empty interfaces for naming/documentation and need allowSingleExtends: true.

Related errors


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

Appendix: source

Thrown at crates/oxc_linter/src/rules/typescript/no_empty_interface.rs:24

use serde::Deserialize;
use serde_json::Value;

use crate::{
    AstNode,
    context::{ContextHost, LintContext},
    rule::{DefaultRuleConfig, Rule},
};

fn no_empty_interface_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("an empty interface is equivalent to `{}`")
        .with_help(
            "Add members to this interface, or use a type alias if it is intentionally empty.",
        )
        .with_label(span)
}

fn no_empty_interface_extend_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("an interface declaring no members is equivalent to its supertype")
        .with_help("Remove this interface and use the extended type directly or add members to this interface.")
        .with_label(span)
}

#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoEmptyInterface {
    /// When set to `true`, allows empty interfaces that extend a single interface.
    #[serde(alias = "allow_single_extends")]
    // for backwards-compatibility, we made a mistake in the naming previously
    allow_single_extends: bool,
}

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Disallow the declaration of empty interfaces.
    ///

View on GitHub (pinned to e1e7af627c)