runtime.boot

Full Stack Systems
Production Mindset

CodeWithMihir

Engineering thoughtful products from interface to infrastructure.

CodeWithMihir

TypeScript Tutorial

TypeScript Optional Properties Explained with Examples

Learn how optional properties work in TypeScript, including the question mark syntax, safe access, optional chaining, and common mistakes.

Welcome back! I am Mihir, and in this lesson we will learn optional properties in TypeScript.

Optional properties describe object fields that may or may not exist.


Optional Property Syntax

Use ? after the property name.

type User = {
  name: string;
  email: string;
  phone?: string;
};

phone?: string means phone is optional.

These are both valid:

const userOne: User = {
  name: "Mihir",
  email: "mihir@example.com",
};

const userTwo: User = {
  name: "Aarav",
  email: "aarav@example.com",
  phone: "9876543210",
};

Optional Means Possibly Undefined

An optional property may be undefined.

function printPhone(user: User): void {
  console.log(user.phone.toUpperCase());
}

TypeScript warns because phone might be missing.

Correct:

function printPhone(user: User): void {
  if (user.phone) {
    console.log(user.phone.toUpperCase());
  }
}

Optional Chaining

Use ?. to safely access optional values.

function printPhone(user: User): void {
  console.log(user.phone?.toUpperCase());
}

If phone is missing, the result is undefined instead of a crash.


Default Values with ??

Use ?? for fallbacks.

function getDisplayPhone(user: User): string {
  return user.phone ?? "No phone provided";
}

?? only uses the fallback when the value is null or undefined.


Optional Properties in API Data

APIs often return optional fields.

type Product = {
  id: number;
  title: string;
  description?: string;
  imageUrl?: string;
};

Before rendering optional fields, check them:

function printProduct(product: Product): void {
  console.log(product.title);

  if (product.description) {
    console.log(product.description);
  }
}

Optional Nested Properties

type User = {
  name: string;
  profile?: {
    bio?: string;
    website?: string;
  };
};

Access safely:

function printBio(user: User): void {
  console.log(user.profile?.bio ?? "No bio");
}

This handles missing profile and missing bio.


Optional Properties vs Union with undefined

These are similar, but not identical in meaning:

type UserA = {
  phone?: string;
};

type UserB = {
  phone: string | undefined;
};

In UserA, the property can be missing.

In UserB, the property must exist, but its value can be undefined.

Most of the time, optional properties are cleaner for fields that may be missing.


Common Mistake: Making Everything Optional

Avoid this:

type User = {
  name?: string;
  email?: string;
  role?: string;
};

If every field is optional, TypeScript cannot guarantee much.

Make required data required:

type User = {
  name: string;
  email: string;
  role?: string;
};

Quick Reference Summary

ConceptExample
Optional propertyphone?: string
Safe checkif (user.phone)
Optional chaininguser.phone?.toUpperCase()
Fallbackuser.phone ?? "No phone"
Nested optionalprofile?: { bio?: string }
May be missingoptional property can be absent

Practice

Create a product type with optional fields:

type Product = {
  title: string;
  price: number;
  discountCode?: string;
};

function printProduct(product: Product): void {
  console.log(product.title);
  console.log(product.discountCode ?? "No discount");
}

Try accessing discountCode.toUpperCase() without checking it.


What You've Learned

You now understand:

  • How to create optional properties
  • Why optional properties may be undefined
  • How to safely access optional values
  • How optional chaining works
  • How ?? provides fallbacks
  • How optional nested properties work
  • Why required fields should stay required

What's Next?

In the next lesson, we will learn Readonly Properties in TypeScript.

We will prevent accidental object mutation with readonly.


Need Help?

  • Have questions, confusion, or want to know more? Contact me

Optional properties are honest documentation: this field may not be there, so handle that case.