🌱BeginnerObject Types & Interfaces

Interfaces

Define object shapes with interface optional properties, readonly, extending, and declaration merging.

Overview

An `interface` in TypeScript describes the shape (structure) of an object. It specifies which properties an object must have and what types those properties are. Any object that has the required properties satisfies the interface TypeScript uses structural typing, not nominal typing. Interfaces support: - **Optional properties** (`?`) may or may not be present - **Readonly properties** (`readonly`) cannot be changed after creation - **Method signatures** define what methods an object must have - **Extending** one interface can extend another (or multiple) - **Declaration merging** multiple declarations of the same interface name are merged Interfaces are erased at compile time no runtime overhead.

Key Points

  • •`interface Name { prop: Type; }` defines an object shape
  • •Optional property: `prop?: Type` may be absent; type is `Type | undefined`
  • •Readonly: `readonly prop: Type` assignable once, then immutable
  • •Method signature: `method(arg: Type): ReturnType` or arrow form `method: (arg: Type) => ReturnType`
  • •Extending: `interface B extends A { ... }` B has all of A's properties plus its own
  • •Multiple inheritance: `interface C extends A, B { ... }`
  • •Declaration merging: redeclaring the same interface name adds properties (useful for extending global types)

Examples

Basic interface with optional and readonly

interface User {
  readonly id: number;    // cannot change after creation
  name: string;
  email: string;
  age?: number;           // optional User | undefined
  role?: "admin" | "user" | "guest";
}

const alice: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  role: "admin",
};

// alice.id = 2;    // Error: Cannot assign to 'id' because it is a read-only property

// Optional property is undefined if not provided
console.log(alice.age);   // undefined

function greetUser(user: User): string {
  return `Hello, ${user.name}!${user.role ? ` [${user.role}]` : ""}`;
}
console.log(greetUser(alice));   // Hello, Alice! [admin]

Interface with methods and extending

interface Shape {
  readonly name: string;
  area(): number;
  perimeter(): number;
  toString(): string;
}

interface ColoredShape extends Shape {
  color: string;
}

interface LabeledShape extends Shape {
  label: string;
}

// Must implement all methods
const circle: ColoredShape = {
  name: "circle",
  color: "red",
  area: () => Math.PI * 5 * 5,
  perimeter: () => 2 * Math.PI * 5,
  toString: () => "Circle(r=5)",
};

console.log(circle.area().toFixed(2));   // 78.54
console.log(circle.toString());          // Circle(r=5)

Index signatures dynamic keys

// When you don't know all property names upfront
interface StringMap {
  [key: string]: string;
}

const translations: StringMap = {
  hello: "hola",
  world: "mundo",
  goodbye: "adios",
};

console.log(translations["hello"]);  // "hola"
translations["thanks"] = "gracias";  // ok

// Mixed: known + dynamic keys
interface Config {
  version: string;                 // known key
  [key: string]: string | number;  // dynamic keys (must be compatible with known)
}

const cfg: Config = {
  version: "1.0",
  timeout: 5000,
  endpoint: "https://api.example.com",
};

Common Mistakes

  • Confusing optional (`?`) with possibly-null `age?: number` means `number | undefined`, not `number | null`
  • Trying to implement an interface on a plain object with extra properties TypeScript uses excess property checking on object literals but not on assigned variables
  • Forgetting that interfaces don't generate any JavaScript they exist only at type-check time

Note

Use `readonly` on all properties that shouldn't change after construction it documents intent and TypeScript enforces it. For function parameters, accepting `Readonly<T>` communicates "I won't mutate this" to callers.

Exercises

Write TypeScript code to solve each exercise. Click Run to compile and execute it right here, then mark as done.

Loading editor…

Completed: 0 / 5 exercises

Knowledge Check

Question 1 of 4

What does TypeScript's structural typing mean for interfaces?