TypeScript Types vs Interfaces: Stop Overthinking It
The types vs interfaces debate consumes more mental energy than it deserves. Here's what actually matters and a simple rule for when to use each.
Every TypeScript tutorial eventually hits the types vs interfaces section. Some treat it as deeply important. The debate generates Stack Overflow answers longer than most novels. The practical reality: for 95% of TypeScript code, it doesn't matter.
The Actual Differences
There are three meaningful distinctions between type aliases and interfaces:
- Declaration merging: interfaces can be declared multiple times and TypeScript merges them. Types cannot — a second declaration with the same name is an error.
- Extending: interfaces use 'extends', types use '&' (intersection). Both achieve similar results but with slightly different syntax.
- Union types: 'type Result = Success | Error' works. Interfaces can't represent a union of two separate types.
The Simple Rule
Use interface when you're defining an object shape that might need to be extended (especially in library code or shared types). Use type when you need unions, intersections, or mapped types. For React component props and most application code, either is fine — pick one and be consistent.
Where the Debate Actually Matters
Library code: if you're writing a library that consumers will use, interfaces are generally better because consumers can augment them via declaration merging. This is how TypeScript lets you extend Express's Request type or add custom properties to a library's types without forking the source.
Complex type transformations: when you're doing mapped types, conditional types, or template literal types, you'll use type aliases because interfaces don't support these patterns.
What Most Teams Actually Do
Most teams pick a default (usually either 'always interface' or 'always type') and apply it consistently. Both choices work. The cost of inconsistency (some files use types, some use interfaces, no clear pattern) is higher than the cost of either choice. Set a linting rule to enforce the team's preference and move on.
ESLint rule
The @typescript-eslint/consistent-type-definitions rule enforces 'interface' or 'type' consistently across a project. Set it to your team's preference and never have the debate again.
Frequently Asked Questions
Are type and interface interchangeable in TypeScript?+
Which should I use for React component props?+
What is declaration merging?+
What's the TypeScript team's official recommendation?+
🔧 Free Tools Used in This Guide
FreeToolKit Team
FreeToolKit Team
We build free browser-based tools and write practical guides that skip the fluff.
Tags: