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.