Atlas

Roadmap

Functions & Objects

Interfaces & Type Aliases

Mar 25, 2026

The Problem

Primitive types like string and number work for single values. But how do you describe the shape of an object?

// Without types — no idea what user looks like
function greet(user) {
  return "Hello, " + user.name
}
typescript

TypeScript offers two tools for this: interfaces and type aliases .

Interfaces

An interface defines the shape of an object.

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

function greet(user: User): string {
  return "Hello, " + user.name
}

const alan: User = { id: 1, name: "Alan", email: "alan@example.com" }
greet(alan)  // "Hello, Alan"
typescript

If you pass an object missing a required field, TypeScript errors immediately.

Optional Properties

Add ? to make a property optional.

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

const user: User = { id: 1, name: "Alan" }  // OK — email not required
typescript

Readonly Properties

readonly prevents a property from being reassigned after creation.

interface User {
  readonly id: number
  name: string
}

const user: User = { id: 1, name: "Alan" }
user.name = "Bob"  // OK
user.id = 2        // Error: Cannot assign to 'id' because it is a read-only property
typescript

Extending Interfaces

Interfaces can extend other interfaces to inherit their properties.

interface Animal {
  name: string
}

interface Dog extends Animal {
  breed: string
}

const dog: Dog = { name: "Rex", breed: "Labrador" }
typescript

Type Aliases

A type alias uses the type keyword and can describe objects the same way as an interface.

type User = {
  id: number
  name: string
  email?: string
}
typescript

Type aliases can also describe union types, which interfaces cannot:

type ID = string | number
type Status = "active" | "inactive" | "pending"  // literal union
typescript

Interface vs Type Alias

Both work for defining object shapes. The key differences:

InterfaceType Alias
Object shapesYesYes
Union typesNoYes
Extendingextends keyword& intersection
Declaration mergingYesNo

Practical rule: Use interface for objects and class contracts. Use type for unions, intersections, and utility types.

Intersection Types

Use & to combine multiple types into one.

type Employee = {
  id: number
  name: string
}

type Manager = Employee & {
  department: string
  reports: number
}

const manager: Manager = {
  id: 1,
  name: "Alan",
  department: "Engineering",
  reports: 5
}
typescript

Index Signatures

Use an index signature when you do not know the property names upfront but you know the types.

interface Scores {
  [subject: string]: number
}

const scores: Scores = {
  math: 95,
  english: 88,
  science: 92
}
typescript

Key Questions

Q: What is the difference between an interface and a type alias in TypeScript?

Both can define the shape of an object. The main differences: type aliases can describe union types (string | number), interfaces cannot. Interfaces support declaration merging — two interface User declarations in the same scope are automatically merged. Interfaces use extends to inherit from other interfaces; type aliases use & for intersections. In practice, use interfaces for object shapes and class contracts, and type aliases for unions, intersections, and mapped types.

Q: What is the difference between ? and readonly on interface properties?

? makes a property optional — it does not need to be present when creating the object. readonly makes a property immutable — it must be provided when creating the object, but cannot be changed afterward.

Q: What is an intersection type?

An intersection type combines multiple types into one using &. The resulting type has all properties from all the combined types. For example, Employee & Manager requires all properties from both Employee and Manager. It is useful for composing types from smaller, reusable pieces.