Kodokon kodokon.com

type vs interface: extends and intersection

Pick the right construct to model and compose your object types without duplicating code.

8 min · 3 questions

Open this lesson in Kodokon

You already know how to declare object types. The real question on a project is choosing between type and interface, then composing existing types without duplicating code. Let's start with the most common scenario: modeling entities that look alike.

TYPESCRIPT
interface User {
  id: number;
  name: string;
}

interface Admin extends User {
  permissions: string[];
}

const admin: Admin = {
  id: 1,
  name: "Ada",
  permissions: ["users:write"],
};
Extending an interface with extends

extends creates a clear relationship: an Admin is a User with extra powers. With a type alias, you get the same result through the intersection operator &, which merges several shapes into one. It's the perfect tool for cross-cutting concerns, like timestamps present on all your entities.

TYPESCRIPT
type Timestamps = {
  createdAt: Date;
  updatedAt: Date;
};

type Product = {
  id: number;
  label: string;
};

type StoredProduct = Product & Timestamps;
Composing types with the & intersection

So which one should you choose? Two differences really matter. First, only type can name a union like 'active' | 'archived'. Second, two interface declarations sharing the same name merge automatically: handy for augmenting a library's types, dangerous when it happens by accident.

TYPESCRIPT
type Status = "active" | "archived";

interface Config {
  locale: string;
}

interface Config {
  debug: boolean;
}

const config: Config = { locale: "fr", debug: true };
Unions are type-only, interface declarations merge

Knowledge check

Make sure you remember the key points of this lesson.

  1. You need to name the type 'draft' | 'published'. Which construct is required?
    • interface
    • type
    • Both work
    • enum
  2. Two interface Config { ... } declarations coexist in the same scope. What happens?
    • An immediate compile error
    • The second one overwrites the first
    • They merge into a single interface
    • The first one takes precedence
  3. Which operator combines two object type aliases into a single type requiring the properties of both?
    • |
    • &
    • extends