TypeScript: types vs interfaces (When to Use Which)

A deep, interview-ready guide to TypeScript types vs interfaces: extension, unions, intersections, declaration merging, and practical patterns for real codebases.

F

Frontend Interview Team

February 08, 2026

~22 min
TypeScript: types vs interfaces (When to Use Which)

Types vs interfaces is one of the most common TypeScript interview questions.

The truth: both can model object shapes. But they differ in a few important ways that matter in real projects.


1) The shared basics

Both can describe object shapes:

type UserType = {
  id: string;
  name: string;
};
 
interface UserInterface {
  id: string;
  name: string;
}

So the interview question is really about the differences.


2) Key difference: declaration merging

Interfaces can merge

interface Config {
  timeout: number;
}
 
interface Config {
  baseUrl: string;
}
 
// Config is now { timeout: number; baseUrl: string }

This is useful for:

  • augmenting library types
  • extending global types

Types cannot merge

If you redeclare a type, it’s an error.


3) Unions and primitives

Types are more flexible

Types can represent unions, primitives, tuples:

type Id = string | number;
type Status = 'idle' | 'loading' | 'success' | 'error';
 
type Point = [number, number];

Interfaces are mainly for object shapes.


4) Extending / composition

Interfaces extend nicely

interface Base {
  id: string;
}
 
interface User extends Base {
  name: string;
}

Types use intersections

type Base = { id: string };
type User = Base & { name: string };

Both are fine. In practice:

  • interfaces read cleaner for object models
  • types are great when you need unions + composition

5) “Prefer interface for public APIs” — why?

Some teams prefer interface for object models because:

  • better error messages (often)
  • easier to extend
  • supports declaration merging

But it’s not a hard rule.


6) Common real-world patterns

Pattern A: Use interface for data models

interface User {
  id: string;
  email: string;
}

Pattern B: Use types for complex derived types

type ApiResult<T> =
  | { ok: true; data: T }
  | { ok: false; error: string };

7) Interview Q&A

Q: When would you use interface over type?

  • For object shapes that you expect to extend/merge (public APIs, library augmentation).

Q: When would you use type over interface?

  • For unions, primitives, tuples, mapped/conditional types.

Q: Can interfaces do unions?

  • Not directly.

Summary

  • Both work for object shapes.
  • Interface supports declaration merging and reads well for models.
  • Type is more general (unions, primitives, tuples, advanced composition).
  • In real code: interface for models, type for complex/derived types is a solid default.