What are optional properties?
Optional properties in TypeScript allow you to define properties within an interface or type alias that may or may not be present on an object conforming to that type. They provide flexibility, especially when dealing with data that might have varying structures or when defining configuration objects where some settings are not mandatory.
Declaring Optional Properties
An optional property is declared by appending a question mark (?) after the property name in an interface or type alias definition. This signals to the TypeScript compiler that the property might not exist on objects of that type.
interface User {
id: number;
name: string;
email?: string; // Optional property
phone?: string; // Another optional property
}
// Valid objects conforming to the User interface:
const user1: User = {
id: 1,
name: "Alice"
};
const user2: User = {
id: 2,
name: "Bob",
email: "bob@example.com"
};
const user3: User = {
id: 3,
name: "Charlie",
email: "charlie@example.com",
phone: "555-1234"
};
Behavior and Type Inference
When a property is marked as optional, its type automatically includes undefined. This means if you access an optional property that isn't present on an object, its value will be undefined. TypeScript's strict null checks (strictNullChecks compiler option) will then require you to handle the possibility of undefined when accessing such properties.
interface Product {
id: number;
name: string;
description?: string;
price: number;
}
const productA: Product = { id: 1, name: "Laptop", price: 1200 };
const productB: Product = { id: 2, name: "Mouse", description: "Wireless mouse", price: 25 };
function printProductDetails(product: Product) {
console.log(`Name: ${product.name}`);
// Accessing an optional property requires a check for undefined
if (product.description) {
console.log(`Description: ${product.description}`);
} else {
console.log("No description available.");
}
// Alternatively, using optional chaining (ES2020+)
console.log(`Description (optional chaining): ${product.description?.toUpperCase() ?? 'N/A'}`);
}
printProductDetails(productA); // No description
printProductDetails(productB); // Wireless mouse
Common Use Cases
- Configuration Objects: When a function or component accepts an options object where not all settings are mandatory.
- Partial Updates: Defining types for objects that represent partial data updates, where only some fields are provided.
- Default Values: Allowing properties to be omitted, with the application logic providing default values if they are missing.
- APIs with Flexible Responses: Modeling data structures from external APIs that may not always return every field.
Interaction with `null`
While an optional property implicitly includes undefined in its type, it does not automatically include null. If a property can be null as well as optional, you must explicitly include null in its type union.
interface Book {
title: string;
author: string;
isbn?: string | null; // Can be string, null, or undefined
}
const book1: Book = { title: "1984", author: "George Orwell" }; // isbn is undefined
const book2: Book = { title: "Brave New World", author: "Aldous Huxley", isbn: null }; // isbn is null
const book3: Book = { title: "The Hobbit", author: "J.R.R. Tolkien", isbn: "978-0345339683" }; // isbn is string