Notifications

No notifications

/Phase 2

Interfaces & Type Aliases

Interfaces and type aliases are how you describe the *shape* of an object in TypeScript. They look almost identical, but each shines in different situations. Knowing when to use which (and how extends and & differ) is the difference between clean code and tangled type errors.

On this page

Detailed Theory

Type aliases

type gives a name to *any* type — primitive, union, tuple, object, function.

type ID = string | number;
type Point = { x: number; y: number };
type Handler = (e: Event) => void;

Interfaces

interface is specialised for object shapes (and callable / constructable types).

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

Used the same way:

const u: User = { id: 1, name: "Ada", email: "ada@x.com" };

Optional & readonly properties

interface User {
  id: number;
  readonly createdAt: Date;   // can't be reassigned after creation
  email?: string;             // may be omitted
}

const u: User = { id: 1, createdAt: new Date() }; // u.createdAt = new Date(); // ❌ u.email = "x@y.com"; // ✅

> readonly is a *compile-time* check only. Nothing prevents JS from mutating at runtime.

Index signatures — open-ended objects

interface StringDict {
  [key: string]: string;
}

const env: StringDict = {}; env.HOME = "/home/rahul"; // ✅ // env.PORT = 3000; // ❌ number not assignable to string

Method shorthand vs property syntax

interface Counter {
  increment(): number;             // method shorthand
  reset: () => void;               // property holding a function
}

For most code these behave the same. Method shorthand is bivariant — looser checking around this — so if you turn on strictFunctionTypes (it's part of strict), prefer the property form for stricter callbacks.

Extending — composition

Interface extends interface

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

const d: Dog = { name: "Rex", breed: "Lab" };

Multiple parents are allowed:

interface Swimmer { swim(): void }
interface Flyer  { fly(): void }
interface Duck extends Animal, Swimmer, Flyer {}

Type alias intersection — &

The type equivalent of extends:

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

Intersections can combine anything, including unions:

type Status = "on" | "off";
type Strict = Status & string;       // still "on" | "off"

But they fail loudly when properties conflict:

type A = { x: string };
type B = { x: number };
type C = A & B;                       // C.x is never — impossible to satisfy

Declaration merging — interfaces only

Two interfaces with the same name merge. Type aliases throw a duplicate-identifier error.

interface User { id: number }
interface User { name: string }
// User now has id AND name

This is what lets libraries (and you!) extend Express's Request or augment global types:

declare global {
  interface Window { myApp: { version: string } }
}

interface vs type — when to use which

NeedPick
Public object/class shapeinterface
Union, tuple, primitive alias, conditional typetype
Library API you might want others to extendinterface (for declaration merging)
Quick local shape with a function in iteither

A useful default: interface for objects, type for everything else. Don't agonise — they're 95 % equivalent.

Excess property checks

Object literals get an extra check that catches typos:

interface Options { url: string; method?: string }

function fetchIt(opts: Options) {}

fetchIt({ url: "/api", methid: "GET" }); // ^^^^^^^ ❌ Object literal may only specify known properties

But assigning through a variable bypasses it:

const o = { url: "/api", methid: "GET" }; // typed as { url: string; methid: string }
fetchIt(o); // ❌ different reason — methid not in Options

To explicitly allow extra props, add an index signature or use as Options.

Class shapes — implements

A class can promise to satisfy an interface:

interface Greeter { greet(): string }

class Hello implements Greeter { greet() { return "hi"; } }

If the class is missing a member, the compiler complains.