type vs interface
An interface describes an object or class shape that can be extended and merged, while a type alias can name any type at all — including unions, tuples, and mapped types — so each is the better tool for a different job.
Learn type vs interface in our free TypeScript course — an interactive lesson with runnable examples, a practice exercise and a quick reference.
Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Think of two ways to define a recipe. An interface is a recipe card pinned to a shared board: anyone can pin extra cards under the same name (merging) and write "based on the pasta recipe, plus..." (extends). A type alias is a sticky note that can say anything — "today's special is soup OR salad OR sandwich" (a union) — but you can't keep adding to the same note later. Different tools, different strengths.
1. For Object Shapes, They're Twins
When all you need is to describe a plain object, type and interface are nearly identical. Both support optional ? members, readonly , methods, and index signatures, and both are completely erased at runtime. For most everyday object shapes, you could swap one for the other and nothing about the running code would change.
2. Interface Superpowers: Merging & extends
Two things only interfaces do. Declaration merging : declare an interface twice with the same name and TypeScript combines the members — invaluable for augmenting types you don't own, like adding a property to the global Window . And extends lets one interface inherit another's members, modelling "is-a-plus-more" relationships cleanly.
3. Type Superpowers: Unions, Tuples & More
A type alias can name any type, not just object shapes. Unions ( ), tuples ( [string, number] ), literal-union "menus," and advanced mapped or conditional types all require a type — an interface simply can't express them. This is the clearest dividing line: anything algebraic belongs to type .
🎯 Your Turn
A literal-union Direction is a classic type alias. Fill in the blank marked ___ with the right literal, then run it.
No blanks this time — just a brief and a starting outline. Build the shape factory yourself, run it, and check your output against the example in the comments.
Practice quiz
For describing a plain object shape, type and interface are:
- Nearly interchangeable
- Completely different
- Both unable to have optional members
- Only usable for classes
Answer: Nearly interchangeable. For a plain object shape both support optional members, readonly, and methods, and both are erased at runtime.
Which feature is unique to interfaces?
- Naming a union type
- Declaration merging
- Naming a tuple type
- Aliasing a primitive
Answer: Declaration merging. Declaring the same interface name twice merges the members; type aliases cannot do this.
Which can ONLY be expressed with a type alias, not an interface?
- An optional member
- A readonly member
- A union like string | number
- A method
Answer: A union like string | number. An interface can only describe an object/function/array shape; unions and tuples require a type alias.
Declaring the same 'type' alias name twice causes:
- A merge of the two
- A duplicate-identifier error
- An automatic union
- Nothing at all
Answer: A duplicate-identifier error. Unlike interfaces, re-declaring a type alias with the same name is a duplicate-identifier error.
Which keyword lets one interface inherit another's members?
- implements
- merges
- extends
- infers
Answer: extends. interface Dog extends Animal inherits Animal's members into Dog.
To combine two type aliases into one shape you use:
- The | operator
- The & operator
- The extends keyword
- The keyof operator
Answer: The & operator. Type aliases combine shapes with the intersection operator &, where interfaces use extends.
At runtime, a type and an interface declaration:
- Both still exist as objects
- Are both erased
- Only the interface survives
- Only the type survives
Answer: Are both erased. Both are purely compile-time constructs and are erased, so they never affect the running output.
Declaration merging is especially useful for:
- Augmenting library or global types you do not own
- Speeding up arrays
- Defining unions
- Replacing classes
Answer: Augmenting library or global types you do not own. Merging lets you add members to types like the global Window without forking the library.
A practical default rule of thumb is to use interface for:
- Unions and tuples
- Public object/class shapes you may extend
- Mapped types
- Primitive aliases
Answer: Public object/class shapes you may extend. Reach for interface for extendable object/class shapes, and type for unions, tuples, and other algebraic types.
Can an interface be declared as a union of two object shapes?
- Yes, with the | syntax
- Yes, using extends
- No, interfaces cannot be unions
- Only if both shapes match
Answer: No, interfaces cannot be unions. interface X = A | B does not parse; unions must use a type alias.