Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Type Aliases in TypeScript: type vs. interface

Type Aliases: type vs. interface

~13 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

Besides interface, there's a SECOND way to name a type: the type keyword. This chapter clarifies WHEN each of the two tools is the better choice – one of the most common questions from TypeScript beginners.

The basics of type

type BookStatus = 'available' | 'borrowed' | 'reserved'; // more on this in chapter 9

type ISBN = string; // a simple alias - NOT its own type, just another name for string

type BookSummary = {
  title: string;
  author: string;
};

type can describe object shapes JUST LIKE interfaceBookSummary above is functionally almost identical to a same-named interface. BUT: type can ADDITIONALLY do things interface CANNOT, as shown by BookStatus (a union of string literals) or ISBN (an alias for a primitive type).

The three actual differences

// 1. Only interface can be extended via MULTIPLE declarations ("declaration merging"):
interface Config {
  name: string;
}
interface Config {
  version: string; // gets AUTOMATICALLY added to Config, no error!
}
// Config now has { name: string; version: string }

// 2. type can describe things that are NOT object shapes:
type Num = number;
type Coordinate = [number, number];
type Status = 'active' | 'inactive';

// 3. interface uses 'extends', type uses '&' (intersection, see chapter 9)
interface Base { name: string; }
interface Extended extends Base { extra: string; }

type BaseT = { name: string };
type ExtendedT = BaseT & { extra: string };

Achtung: "Declaration merging" (point 1) is usually a SOURCE OF BUGS, not a feature you actively want – two ACCIDENTALLY same-named interfaces merge SILENTLY, instead of showing an error. type behaves "more safely" here: two same-named type declarations are ALWAYS an error ("Duplicate identifier").

This tutorial's practical rule of thumb

  • interface for object shapes describing a "thing" with identity (our Book, Author, Member interfaces from chapter 7) – especially when later extension via extends is likely.
  • type for EVERYTHING else: union types, function types (like CompareFunction from chapter 6), aliases for primitive types, tuple types.

This rule is a CONVENTION, not a technical necessity – many successful TypeScript projects use exclusively type for EVERYTHING. What matters is CONSISTENCY within a project, not the "perfectly correct" choice in each individual case.

In practice: introducing a more precise book status

Our current isBorrowed: boolean can only represent TWO states – in reality there's also "reserved" (someone's waiting for it). Let's replace the boolean with a more precise type:

src/models/Book.ts
import { Author } from './Author.js';

export type BookStatus = 'available' | 'borrowed' | 'reserved';

export interface Book {
  readonly isbn: string;
  title: string;
  author: Author;
  publicationYear: number;
  pageCount: number;
  genres: string[];
  status: BookStatus; // replaces the old isBorrowed: boolean
  coverImageUrl?: string;
}

BookStatus gets explained in detail in chapter 9 (union types) – used here as a practical preview showing WHY type is the better choice than interface for this use case (an interface can't express a value enumeration like this).

Tipp: If you're unsure: start with interface for objects. Once you need something interface CAN'T do (union, tuple, function type), reach for type. That way you never risk choosing "wrong".