interface vs type in TypeScript
In day-to-day TS code we reach for both
interface
andtype
. I tend to use interfaces for object shapes and type aliases for literal unions liketype Username = 'bob' | 'kelly'
. I enforce it with theinterface-over-type-literal
rule. But what’s the precise difference? Here’s a summary.
What the Docs Say
Type aliases can act like interfaces; however, there are subtle differences. Interfaces create a new name; type aliases do not. Prefer interfaces when possible for better extension.
Use type aliases when you need unions/tuples or shapes interfaces can’t express.
Docs: http://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases
Key Points
- Type aliases don’t create a nominal type; interfaces do.
- Prefer interfaces for extensibility.
- Use type aliases for unions, tuples, or when you don’t want to expose lots of members.
Rule: interface-over-type-literal
This lint rule flags type literals defined via type
. Internally it checks:
isTypeAliasDeclaration
isTypeLiteralNode
Example from the rule’s tests:
type T = { x: number; } // ❌ flagged
type U = string; // ✅
type V = { x: number; } | { y: string; }; // ❌ flagged
export type W<T> = { x: T }; // ❌ flagged
type Record<T, U> = { [K in T]: U }; // ✅ mapped types are allowed
Takeaway
Use whichever fits the shape, but understand how tools treat them differently. Then enjoy the safety TS provides.