oxc-project/oxc · warning · OxcDiagnostic
an interface declaring no members is equivalent to its super
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).
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)
Solutions
- Use the extended type directly at the usage sites and delete the empty interface
- Add members so the interface actually refines its supertype
- 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
- Alias supertypes with `type Foo = Bar` when you only need a new name, not an interface
- Use interfaces only when they add or refine members
- Set allowSingleExtends deliberately if empty single-extend interfaces are an accepted local idiom
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
- Use a property signature instead of a method signature.
- Use a method signature instead of a property signature.
- an empty interface is equivalent to `{}`
- encountered allocation error
- Do not use @ts-{ts_comment_name} because it alters compilati
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/9b67e0d796414b40.
Report an issue: GitHub.