What is the difference between interface and type in TypeScript?

Both describe object shapes, but interfaces are extendable with declaration merging; type aliases are more flexible and work for unions, primitives, and tuples.

TypeScript

Overview

`interface` and `type` can often be used interchangeably for describing object shapes. The differences are subtle but matter in specific situations: declaration merging, extending, and what kinds of types each can express.

Key Points

  • •Both can describe object shapes and be extended interfaces via `extends`, types via `&` (intersection).
  • •Only `interface` supports declaration merging: declaring the same interface name twice merges them.
  • •`type` can express unions (`A | B`), intersections, primitives, tuples, and mapped types `interface` cannot.
  • •Interfaces produce clearer error messages in most cases because TypeScript names them.
  • •Convention in most codebases: `interface` for public API shapes; `type` for unions, utility types, and complex compositions.

Examples

Extending: both work, different syntax

typescript
// interface extends
interface Animal   { name: string; }
interface Dog extends Animal { breed: string; }

// type intersection
type Animal = { name: string };
type Dog    = Animal & { breed: string };

Declaration merging (interface only)

typescript
// Useful for augmenting third-party types
interface Window { myPlugin: MyPlugin; }
interface Window { analytics: Analytics; }
// Both declarations are merged into one Window type

// type aliases CANNOT be merged this is an error:
type User = { name: string };
type User = { age: number }; // Error: Duplicate identifier 'User'

What only type can do

typescript
// Union types
type Status = 'active' | 'inactive' | 'pending';

// Tuple types
type Point = [number, number];

// Utility types with conditional logic
type Nullable<T> = T | null;
type ReadonlyUser = Readonly<User>;

Pro Tip

Pick one and be consistent within a codebase. Many large TypeScript projects (including TypeScript itself) use `interface` for object shapes and `type` for everything else. The performance difference is negligible.