Skip to content

Objects & Type Aliases

Objects are the backbone of JavaScript. TypeScript builds on this by letting you describe the shape of an object—what properties it has, what types those properties hold, and which ones are optional or immutable. This is where TypeScript starts to feel like a real design tool rather than just a type checker.


Inline Types

Inline types let you describe an object’s structure directly where it’s used.

const user: { name: string; age: number } = {
  name: "Alice",
  age: 30
}

Inline types are great for:

  • small, one‑off objects
  • function parameters
  • quick prototypes

Example in a function:

function printUser(user: { name: string; age: number }) {
  console.log(`${user.name} is ${user.age}`)
}

When inline types become a problem

Inline types get messy when:

  • the same shape is used in multiple places
  • the object has many properties
  • you want to evolve the shape over time

That’s where type aliases and interfaces come in.


Type Aliases vs Interfaces

TypeScript gives you two ways to name object shapes:

  • type (type alias)
  • interface

Both can describe objects, but they have different strengths.


Type Aliases

A type alias gives a name to any type: object, union, primitive, function, etc.

type User = {
  name: string
  age: number
}

Use type aliases when:

  • you need unions
  • you need intersections
  • you want to describe non‑object types
  • you want maximum flexibility

Example:

type ID = string | number

Interfaces

Interfaces are specifically for describing object shapes.

interface User {
  name: string
  age: number
}

Interfaces support:

  • extension
  • declaration merging
  • OOP‑style modeling

Extending interfaces

interface Person {
  name: string
}

interface Employee extends Person {
  role: string
}

Declaration merging

If you declare the same interface twice, TypeScript merges them:

interface Settings {
  theme: string
}

interface Settings {
  language: string
}

// Resulting type:
{
  theme: string
  language: string
}

This is not possible with type aliases.


Type Alias vs Interface: When to Use Which

Use Case Type Alias Interface
Object shapes
Extending types ✔ (via intersections) ✔ (native extends)
Declaration merging
Unions (A | B)
Functions, primitives, tuples

Rule of thumb

If it’s an object and you want extensibility → interface

If it’s anything else or needs unions/intersections → type alias

Both are valid; consistency matters more than the choice.


Optional & Readonly Properties

TypeScript lets you express more nuanced object shapes.


Optional Properties (?)

Use ? when a property may or may not exist.

interface User {
  name: string
  age?: number
}

const u1: User = { name: "Alice" }        // ✔ OK
const u2: User = { name: "Bob", age: 40 } // ✔ OK

This is extremely useful for:

  • partial updates
  • API responses
  • configuration objects

Readonly Properties

Use readonly to prevent reassignment.

interface User {
  readonly id: string
  name: string
}

const user: User = {
  id: "abc123",
  name: "Alice"
}

user.name = "Bob"   // ✔ OK
user.id = "xyz999"  // ❌ Error: Cannot assign to 'id'

Readonly is perfect for:

  • database IDs
  • timestamps
  • values that should never change after creation

Putting It All Together

Here’s a realistic example combining everything:

type ID = string | number

interface User {
  readonly id: ID
  name: string
  email?: string
}

function createUser(id: ID, name: string): User {
  return { id, name }
}

const user = createUser(1, "Alice")

user.name = "Bob"     // ✔ OK
user.email = "bob@example.com" // ✔ OK
user.id = 2           // ❌ Error: readonly

This is the kind of clarity and safety JavaScript simply cannot provide on its own.


Summary

In this lesson, you learned:

1. Inline types

  • Quick and convenient
  • Best for small, local shapes

2. Type aliases vs interfaces

  • Type aliases → flexible, support unions
  • Interfaces → extendable, mergeable, great for object modeling

3. Optional & readonly properties

  • ? marks properties that may be missing
  • readonly prevents accidental mutation

These tools form the foundation of TypeScript’s object modeling capabilities and will be used throughout the rest of the course.