Home/Learn/JavaScript & TypeScript/Interfaces, Type Aliases and Structural Typing

Interfaces, Type Aliases and Structural Typing

Intermediate
TypeScript

TypeScript compares shapes, not names. Two unrelated types with the same members are interchangeable — the opposite of how Java works.

Overview

Java is nominally typed: a class implements an interface only if it says so. TypeScript is structurally typed: if an object has the required members, it fits, regardless of where it came from or what it is called. This is the single biggest mental adjustment for a backend engineer, and it is what makes TypeScript pleasant to use with plain object literals and third-party data. The related question — interface or type alias — matters much less than people argue; both describe object shapes, and the practical differences are narrow.

Structural Typing

Shape is identity. Nothing needs to declare a relationship.

Same shape means same type
interface Point { x: number; y: number }

class Vector { constructor(public x: number, public y: number) {} }

function length(p: Point) { return Math.hypot(p.x, p.y) }

length(new Vector(3, 4))          // fine — Vector has x and y
length({ x: 3, y: 4 })            // fine — the literal has x and y
// In Java, Vector would have to declare 'implements Point'.

// Extra properties are allowed... except on fresh object literals
const v = { x: 3, y: 4, z: 5 }
length(v)                         // OK — v is a variable
length({ x: 3, y: 4, z: 5 })      // Error — excess property check
// The literal check exists to catch typos in options objects.

interface vs type

Both describe objects. The differences that actually come up.

Unions need type; augmentation needs interface
interface User { id: number; name: string }
type User2 = { id: number; name: string }        // equivalent

// Extension
interface Admin extends User { role: string }
type Admin2 = User2 & { role: string }           // intersection

// Only 'type' can express these
type Id = string | number                        // unions
type Pair = [string, number]                     // tuples
type Getter = () => User                         // (interfaces can too, awkwardly)
type Keys = keyof User                           // mapped/computed types

// Only 'interface' merges declarations
interface Window { myApp: App }       // adds to the existing Window
// which is how you augment third-party or global types

// In practice: 'interface' for object shapes you may extend or augment,
// 'type' for everything else. Being consistent matters more than the choice.

Modifiers and Index Signatures

Optional, readonly, and typing objects with dynamic keys.

readonly, optional, and Record
interface Problem {
  readonly id: string          // assignable only at creation
  title: string
  hint?: string                // string | undefined
  tags: readonly string[]      // no push, no mutation
}

// Index signature — unknown keys, known value type
interface Scores { [topic: string]: number }
const s: Scores = { arrays: 80, graphs: 65 }

// Record is the same thing, more readable
type Scores2 = Record<string, number>

// With a closed key set, prefer this — it catches missing keys
type Level = 'easy' | 'medium' | 'hard'
type Counts = Record<Level, number>
const counts: Counts = { easy: 1, medium: 2 }   // Error: 'hard' is missing

// readonly is compile-time only — Object.freeze is the runtime version

Key Points to Remember

  • 1TypeScript is structurally typed — a value fits a type if it has the right shape, with no declared relationship
  • 2Fresh object literals get an excess-property check that variables do not, which catches option typos
  • 3Only type aliases can express unions, tuples and mapped types; only interfaces merge across declarations
  • 4readonly and optional are compile-time only — Object.freeze is the runtime equivalent
  • 5Record<Level, number> over an index signature when the keys are a known set, because missing keys are then errors

Interview Questions

Sign in to ask Aria
1

What is structural typing and how does it differ from Java's nominal typing?

Medium
2

When must you use a type alias rather than an interface?

Medium
3

Why does passing an object literal with an extra property fail, when passing a variable with the same extra property succeeds?

Hard

Ask Aria about Interfaces, Type Aliases and Structural Typing

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…