Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
TypeScript Interfaces  ›  Lesson

Types vs Interfaces

Types vs Interfaces 12 minInterfaces describe object shapes and can be reopened and extended; type aliases can name any type, including unions and tuples, but cannot be reopened.

Types vs Interfaces

type Task = {...} and interface Task {...} both work, and teams argue about which to use. The practical answer is short: they overlap for object shapes, and each has a few things only it can do. Learn those few things and the choice becomes easy.

The rule

Interfaces describe objects and can be reopened; aliases name anything but are closed.

Where they are the same. For a plain object shape, these are interchangeable:

interface TaskA { id: number; title: string }
type TaskB = { id: number; title: string };

Both support optional and readonly members, methods, and being implemented by a class. Both are erased at compile time.

Only a type alias can name something that is not an object shape:

type Status = "todo" | "doing" | "done";   // union
type Pair = [number, string];               // tuple
type TaskId = number;                        // primitive
type TaskFilter = (t: TaskA) => boolean;     // function type

Only an interface can be reopened. Declaring the same interface name twice merges the members, which is called declaration merging:

interface Settings { theme: string }
interface Settings { pageSize: number }
// Settings now has both theme and pageSize

Doing the same with type is a duplicate-name error. Merging is how you add fields to types you do not own, such as the browser's Window or a library's options interface.

Extending. Interfaces use extends and report conflicting members as errors. Aliases combine with &, where a conflict quietly becomes never.

Many teams settle on a simple convention: interfaces for object shapes, type aliases for everything else. Others use aliases everywhere for consistency. Either is fine if applied consistently.

The shortcut

Ask two questions in order:

  1. "Is it an object shape?" No → it must be a type alias.
  2. "Do I need to add to it from elsewhere?" Yes → it must be an interface. Otherwise, follow the team's convention.
Choosing for the task trackerStep 1 of 4
  1. Status

    Not an object shape, it is a union. Type alias: type Status = ....

The trap: accidentally declaring the same interface name twice in one scope and getting a merged monster instead of an error. If a type has members you never wrote, search for a second declaration.

Drills

Answer fast — trust the rule.

quick drill

Which can only be written as a type alias?

quick drill

What happens when interface Settings is declared twice with different members?

quick drill

What happens when type Settings is declared twice in the same scope?

quick drill

You need to add a tracker property to the browser's global Window type. What do you use?

Remember

  • Interfaces describe objects and can be reopened; aliases name anything but are closed.
  • Ask: is it an object shape? Do I need to add to it from elsewhere?
  • Trap: a repeated interface name merges silently instead of erroring.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainPick one and justify it

For each, say whether you would use an interface or a type alias, and why: (a) the shape of a Task object, (b) Status as "todo", "doing" or "done", (c) a [number, string] pair, (d) adding a field to a library's existing Window declaration.