Skip to main content

prefer-interface

Disallow equivalent type aliases when an interface declaration can be used.

Targeted pattern scopeโ€‹

This rule inspects TSTypeAliasDeclaration nodes whose right-hand side is one of:

  • an object type literal,
  • a function type,
  • an intersection type (when allowIntersection is false and conversion is safe).

What this rule reportsโ€‹

This rule reports type aliases that can be rewritten as interfaces without changing semantics, and provides both autofix and suggestion output.

Why this rule existsโ€‹

For interface-compatible shapes, interfaces can provide clearer extension patterns and better type-display ergonomics. Standardizing on interfaces for these cases reduces style drift and improves readability.

โŒ Incorrectโ€‹

type Person = {
name: string;
age: number;
};
type Comparator<T> = (left: T, right: T) => number;

โœ… Correctโ€‹

interface Person {
name: string;
age: number;
}
interface Comparator<T> {
(left: T, right: T): number;
}
type Worker = Person | Robot;

Behavior and migration notesโ€‹

Lifecycle: Deprecated and frozen since v1.0.0 and available until v2.0.0. Use instead: @typescript-eslint/consistent-type-definitions.

Optionsโ€‹

type Options = [
{
allowIntersection?: boolean;
allowLocal?: boolean;
}?,
];

Default configurationโ€‹

[{}];

Effective behavior with defaults:

{ allowIntersection: true, allowLocal: false }
  • allowIntersection: false enables reporting safe intersection aliases that can become interface ... extends ....
  • allowLocal: true skips non-exported aliases.

โš ๏ธ Intersection conversion uses type information and intentionally bails out on unsafe forms (for example unions in referenced members).

Additional examplesโ€‹

With allowIntersection: false:

interface Name {
name: string;
}

interface Age {
age: number;
}

type User = Name & Age;

is converted to:

interface Name {
name: string;
}

interface Age {
age: number;
}

interface User extends Name, Age {}

ESLint flat config exampleโ€‹

import etcMisc from "eslint-plugin-etc-misc";

export default [
{
plugins: { "etc-misc": etcMisc },
rules: {
"etc-misc/prefer-interface": [
"error",
{
allowIntersection: false,
allowLocal: true,
},
],
},
},
];

When not to use itโ€‹

Disable this rule if your project intentionally standardizes on type aliases for interface-compatible shapes.

Package documentationโ€‹

Rule catalog ID: R058

Further readingโ€‹

Adoption resourcesโ€‹

  • Start at warning level in CI, then move to error after cleanup.
  • Use focused codemods/autofix batches per package or directory.