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
allowIntersectionisfalseand 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: falseenables reporting safe intersection aliases that can becomeinterface ... extends ....allowLocal: trueskips 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โ
- TypeScript Handbook: Interfaces
- TypeScript Handbook: Type Aliases
- TypeScript Performance: Preferring Interfaces Over Intersections
Adoption resourcesโ
- Start at warning level in CI, then move to error after cleanup.
- Use focused codemods/autofix batches per package or directory.