โ† TypeScript Foundations

Interfaces and Types

~280 words ยท 2 min read

Interfaces and Type Aliases

TypeScript offers two main ways to describe object shapes: interface and type. They overlap heavily, but each has strengths.

Defining Object Shapes

An interface declares the properties an object must have, along with their types.

interface User {
    id: number;
    name: string;
    email?: string;   // optional
}

const u: User = { id: 1, name: "Ada" };

Optional vs Required

A property marked with ? is optional โ€” it may be present or absent. Without the ?, the property is required and omitting it is a compile error.

interface Post {
    title: string;      // required
    subtitle?: string;  // optional
}

readonly

The readonly modifier prevents reassignment after the object is created. It is checked at compile time only.

interface Config {
    readonly apiKey: string;
}
const c: Config = { apiKey: "secret" };
// c.apiKey = "new";   // error: readonly

Extending Interfaces

Interfaces can extend others, inheriting their members. This is the primary way to build composable type definitions.

interface Animal {
    name: string;
}
interface Dog extends Animal {
    bark(): void;
}

interface vs type

A type alias can name any type โ€” primitives, unions, tuples โ€” while an interface specifically describes object shapes. Interfaces also support declaration merging (two declarations of the same name combine); type aliases do not.

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

Convention: use interface for object shapes you expect to extend or implement, and type for unions, intersections, and utility aliases. Both compile to the same erased JavaScript.