Nested object types in TypeScript refer to object types that include other object types as properties. This allows you to define complex, hierarchical data structures with strong typing.
Defining Nested Object Types
You can define nested types either inline or using separate type
or interface
declarations.
Example: Using Inline Definition
type User = {
name: string;
address: {
street: string;
city: string;
postalCode: string;
};
};
const user: User = {
name: "Alice",
address: {
street: "123 Main St",
city: "Springfield",
postalCode: "12345",
},
};
Example: Using Separate Types
type Address = {
street: string;
city: string;
postalCode: string;
};
type User = {
name: string;
address: Address;
};
const user: User = {
name: "Bob",
address: {
street: "456 Elm St",
city: "Shelbyville",
postalCode: "67890",
},
};
Nested Optional Properties
You can make nested properties optional by using the ?
modifier.
type User = {
name: string;
address?: {
street: string;
city: string;
};
};
const user1: User = { name: "Charlie" }; // Address is optional
const user2: User = {
name: "Dana",
address: { street: "789 Oak Ave", city: "Metropolis" }
};
Accessing Nested Properties
To safely access nested properties, you can use optional chaining (?.
) to avoid runtime errors.
console.log(user1.address?.street); // Undefined if address is not present
Nested Readonly Properties
Use readonly
to make nested properties immutable.
type Address = {
readonly street: string;
readonly city: string;
};
type User = {
name: string;
readonly address: Address;
};
const user: User = {
name: "Eve",
address: { street: "101 Maple Rd", city: "Gotham" },
};
// user.address.street = "102 Maple Rd"; // Error: Cannot assign to 'street'
Deeply Nested Object Types
For complex structures, you can nest multiple levels of objects.
type Organization = {
name: string;
departments: {
name: string;
employees: {
name: string;
position: string;
}[];
}[];
};
const org: Organization = {
name: "TechCorp",
departments: [
{
name: "Engineering",
employees: [
{ name: "Alice", position: "Developer" },
{ name: "Bob", position: "Engineer" },
],
},
{
name: "HR",
employees: [{ name: "Charlie", position: "Recruiter" }],
},
],
};
Utility Types for Nested Structures
- Partial: Make all nested properties optional.
type PartialOrganization = Partial<Organization>; const org: PartialOrganization = { name: "TechCorp" };
- Pick/Omit: Work with specific nested properties.
type DepartmentOnly = Pick<Organization, "departments">;
- Record: Create dynamic nested structures.
type EmployeeRoles = Record<string, { name: string; position: string }>;
Summary
Nested object types in TypeScript allow you to create structured, hierarchical data types with ease. By combining features like optional properties, readonly properties, and utility types, you can model real-world scenarios with strong typing and robust type checking.