Defining Shapes: Interfaces and Types

In TypeScript, there are two primary ways to define the "Shape" of an object: Interfaces and Type Aliases. While they are very similar, they have distinct behaviors that make them better suited for different architectural scenarios.


1. Interfaces: The Extendable Contract

An interface is the standard way to describe the structure of an object. Their primary strength is their ability to be Extended via inheritance.

interface User {
    id: number;
    username: string;
}

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

2. Type Aliases: The Flexible Alias

A type alias is a name for any type—not just objects, but also primitives, unions, and tuples. Their primary strength is their Composability.

type ID = number | string; // Union type
type Point = { x: number; y: number };

type AppConfig = {
    apiKey: string;
} & Point; // Intersection operator

3. When to use which?

Use Interface when:

Use Type when:


4. Optional and Readonly Properties

Both systems allow you to control the accessibility of properties:

interface Document {
    readonly id: string;
    title: string;
    tags?: string[];
}

Interview Pro-Tips: Declaration Merging

If an interviewer asks "What is one thing an interface can do that a type cannot?", mention Declaration Merging. This allows you to add new properties to existing types (like window or ProcessEnv) without modifying the original source code.


Technical Summary

  1. Interface: The industry standard for object shapes and inheritance.
  2. Type Alias: Used for unions, intersections, and primitives.
  3. Structural: Both systems are structural—if the shape matches, the type matches.