TypeScript Objects

An object groups related data and behavior under one name. In TypeScript, objects have a defined shape — a set of properties with specific types. This shape tells TypeScript exactly what properties the object must have, what type each property holds, and whether any property is optional. Typed objects prevent typos in property names and ensure the correct data gets assigned.

What Is an Object Shape?

  Object Shape (type definition):
  +-----------+----------+
  | Property  |  Type    |
  +-----------+----------+
  | name      | string   |
  | age       | number   |
  | enrolled  | boolean  |
  +-----------+----------+

  Actual Object (value):
  +-----------+------------------+
  | name      | "Sanjay"         |
  | age       | 24               |
  | enrolled  | true             |
  +-----------+------------------+

Declaring an Object with a Type

// Inline object type annotation
let student: { name: string; age: number; enrolled: boolean } = {
    name: "Sanjay",
    age: 24,
    enrolled: true
};

console.log(student.name);     // Sanjay
console.log(student.age);      // 24
console.log(student.enrolled); // true

Accessing and Modifying Properties

let book: { title: string; author: string; pages: number; available: boolean } = {
    title: "Clean Code",
    author: "Robert C. Martin",
    pages: 431,
    available: true
};

// Dot notation access
console.log(book.title);  // Clean Code

// Bracket notation access
console.log(book["author"]); // Robert C. Martin

// Modify a property
book.available = false;
console.log(book.available); // false

// Adding a property that wasn't declared causes an error
book.price = 499; // Error: Property 'price' does not exist on type {...}

Optional Properties

Adding ? after a property name makes it optional. The object can exist without that property, and its type becomes the declared type or undefined.

let employee: {
    name: string;
    department: string;
    phoneNumber?: string;   // optional
    extension?: number;     // optional
} = {
    name: "Neha Sharma",
    department: "Engineering"
    // phoneNumber and extension not required
};

console.log(employee.name);        // Neha Sharma
console.log(employee.phoneNumber); // undefined

Readonly Properties

A readonly property can be set when the object is created but cannot be changed afterward. This is perfect for ID fields, creation timestamps, and other immutable data.

let order: {
    readonly orderId: number;
    product: string;
    quantity: number;
} = {
    orderId: 10045,
    product: "Keyboard",
    quantity: 2
};

order.quantity = 3;    // Allowed
order.orderId = 10046; // Error: Cannot assign to 'orderId' because it is a read-only property.

Nested Objects

Objects can contain other objects as properties, creating a nested structure that mirrors real-world data.

let student: {
    name: string;
    age: number;
    address: {
        city: string;
        state: string;
        pincode: number;
    };
} = {
    name: "Lakshmi",
    age: 21,
    address: {
        city: "Hyderabad",
        state: "Telangana",
        pincode: 500032
    }
};

console.log(student.address.city);    // Hyderabad
console.log(student.address.pincode); // 500032

Object as Function Parameter

Passing an object to a function with a typed shape enforces the correct structure at the call site.

function displayProduct(product: { name: string; price: number; inStock: boolean }): void {
    let status = product.inStock ? "Available" : "Out of Stock";
    console.log(product.name + " | ₹" + product.price + " | " + status);
}

displayProduct({ name: "Headphones", price: 1599, inStock: true });
// Output: Headphones | ₹1599 | Available

displayProduct({ name: "Mouse", price: 799, inStock: false });
// Output: Mouse | ₹799 | Out of Stock

Object Destructuring

Object destructuring extracts specific properties into named variables in one line, making code cleaner and more readable.

let course: { title: string; instructor: string; duration: number; free: boolean } = {
    title: "TypeScript Mastery",
    instructor: "Aarav Singh",
    duration: 40,
    free: false
};

// Destructure specific properties
let { title, instructor, duration } = course;

console.log(title);      // TypeScript Mastery
console.log(instructor); // Aarav Singh
console.log(duration);   // 40

Index Signatures

When an object needs to hold a dynamic set of keys (not known in advance), an index signature defines the type of each key and its corresponding value.

// Object where keys are subject names and values are marks
let reportCard: { [subject: string]: number } = {
    Mathematics: 92,
    Science: 88,
    English: 79,
    History: 84
};

console.log(reportCard["Mathematics"]); // 92
reportCard["Computer Science"] = 95;    // Adding new key is allowed
console.log(reportCard["Computer Science"]); // 95

Object Properties Summary

Property ModifierSyntaxMeaning
Requiredname: stringMust be present in every object
Optionalname?: stringCan be omitted
Readonlyreadonly id: numberCannot change after creation
Dynamic key[key: string]: numberAccepts any string key with number value

Practical Example

// Library book management
let libraryBook: {
    readonly bookId: number;
    title: string;
    author: string;
    totalCopies: number;
    availableCopies: number;
    genre?: string;
} = {
    bookId: 3001,
    title: "Atomic Habits",
    author: "James Clear",
    totalCopies: 5,
    availableCopies: 3,
    genre: "Self-Help"
};

function borrowBook(book: typeof libraryBook): void {
    if (book.availableCopies > 0) {
        book.availableCopies--;
        console.log("Borrowed: " + book.title + " | Remaining: " + book.availableCopies);
    } else {
        console.log("No copies available for: " + book.title);
    }
}

borrowBook(libraryBook); // Borrowed: Atomic Habits | Remaining: 2
borrowBook(libraryBook); // Borrowed: Atomic Habits | Remaining: 1

Leave a Comment