A nested object is an object that contains another object as one of its properties. In TypeScript, interfaces and type aliases can be used to define the structure of nested objects and their properties.
A nested object is an object placed inside another object.
const student = {
name: "Amit",
address: {
city: "Patna",
pin: 800001
}
};
Here, address is a nested object inside
the student object.
Use dot notation to access properties inside a nested object.
console.log(
student.address.city
);
console.log(
student.address.pin
);
An interface can define the structure of a nested object.
interface Student {
name: string;
address: {
city: string;
pin: number;
};
}
const student: Student = {
name: "Amit",
address: {
city: "Patna",
pin: 800001
}
};
A separate interface can be created for the nested object.
interface Address {
city: string;
pin: number;
}
interface Student {
name: string;
address: Address;
}
const student: Student = {
name: "Amit",
address: {
city: "Patna",
pin: 800001
}
};
This approach makes complex structures easier to organize.
A nested object can contain several properties.
interface Student {
name: string;
address: {
houseNo: number;
street: string;
city: string;
state: string;
pin: number;
};
}
const student: Student = {
name: "Amit",
address: {
houseNo: 101,
street: "Main Road",
city: "Patna",
state: "Bihar",
pin: 800001
}
};
Every required property must follow the structure defined by the interface.
Properties inside a nested object can also be optional.
interface Student {
name: string;
address: {
city: string;
pin: number;
landmark?: string;
};
}
const student: Student = {
name: "Amit",
address: {
city: "Patna",
pin: 800001
}
};
The entire nested object can also be optional.
interface Student {
name: string;
address?: {
city: string;
pin: number;
};
}
const student: Student = {
name: "Amit"
};
Here, address does not have to be provided.
If a nested object is optional, check it before accessing its properties.
interface Student {
name: string;
address?: {
city: string;
pin: number;
};
}
const student: Student = {
name: "Amit"
};
if (student.address) {
console.log(
student.address.city
);
}
Type aliases can also describe nested objects.
type Student = {
name: string;
address: {
city: string;
pin: number;
};
};
const student: Student = {
name: "Rahul",
address: {
city: "Delhi",
pin: 110001
}
};
Objects can contain multiple levels of nested objects.
interface Student {
name: string;
address: {
city: string;
location: {
latitude: number;
longitude: number;
};
};
}
const student: Student = {
name: "Amit",
address: {
city: "Patna",
location: {
latitude: 25.5941,
longitude: 85.1376
}
}
};
console.log(
student.address.location.latitude
);
console.log(
student.address.location.longitude
);
A nested object can contain an array.
interface Student {
name: string;
academic: {
course: string;
marks: number[];
};
}
const student: Student = {
name: "Amit",
academic: {
course: "TypeScript",
marks: [
80,
85,
90
]
}
};
console.log(
student.academic.course
);
console.log(
student.academic.marks
);
console.log(
student.academic.marks[0]
);
A nested object can contain an array of objects.
interface Student {
name: string;
courses: {
name: string;
duration: number;
}[];
}
const student: Student = {
name: "Amit",
courses: [
{
name: "TypeScript",
duration: 3
},
{
name: "React Native",
duration: 6
}
]
};
console.log(
student.courses[0].name
);
console.log(
student.courses[1].duration
);
Array indexes can be used to access individual nested objects.
A nested object can contain function properties.
interface Student {
name: string;
profile: {
age: number;
greet: () => void;
};
}
const student: Student = {
name: "Amit",
profile: {
age: 20,
greet: () => {
console.log("Hello");
}
}
};
student.profile.greet();
Normal nested properties can be updated.
interface Student {
name: string;
address: {
city: string;
pin: number;
};
}
let student: Student = {
name: "Amit",
address: {
city: "Patna",
pin: 800001
}
};
student.address.city =
"Delhi";
student.address.pin =
110001;
A nested object property can be marked as readonly.
interface Student {
readonly address: {
city: string;
pin: number;
};
}
const student: Student = {
address: {
city: "Patna",
pin: 800001
}
};
// Cannot replace address:
// student.address = {
// city: "Delhi",
// pin: 110001
// };
If the properties inside the nested object should also be readonly, declare them individually.
interface Student {
address: {
readonly city: string;
readonly pin: number;
};
}
const student: Student = {
address: {
city: "Patna",
pin: 800001
}
};
// student.address.city = "Delhi";
// Error
A function can accept an object containing nested data.
interface Student {
name: string;
address: {
city: string;
pin: number;
};
}
function showStudent(
student: Student
) {
console.log(
student.name
);
console.log(
student.address.city
);
}
showStudent({
name: "Amit",
address: {
city: "Patna",
pin: 800001
}
});
API responses often contain nested objects.
interface Product {
id: number;
name: string;
category: {
id: number;
name: string;
};
}
const product: Product = {
id: 101,
name: "Laptop",
category: {
id: 10,
name: "Electronics"
}
};
React component props can contain nested objects.
interface UserProps {
user: {
name: string;
age: number;
};
}
function UserCard(
props: UserProps
) {
return (
<div>
<h3>
{props.user.name}
</h3>
<p>
Age: {props.user.age}
</p>
</div>
);
}
React Native components can also receive nested objects through typed props.
interface UserProps {
user: {
name: string;
city: string;
};
}
const UserCard = (
props: UserProps
) => {
return (
<View>
<Text>
{props.user.name}
</Text>
<Text>
{props.user.city}
</Text>
</View>
);
};
Optional chaining ?. can safely access a property
when an object may be undefined.
interface Student {
name: string;
address?: {
city: string;
};
}
const student: Student = {
name: "Amit"
};
console.log(
student.address?.city
);
If address does not exist, the expression does
not throw an error.
A common mistake is providing a nested object with missing required properties.
interface Student {
name: string;
address: {
city: string;
pin: number;
};
}
// Incorrect:
// const student: Student = {
// name: "Amit",
// address: {
// city: "Patna"
// }
// };
The pin property is required, so it must be supplied.
Nested objects are useful when related information needs to be grouped together.
interface Student {
id: number;
name: string;
personal: {
age: number;
contact: {
phone: string;
email: string;
};
};
academic: {
course: string;
marks: number[];
};
}
This interface contains multiple levels of nested data.
interface Address {
city: string;
state: string;
pin: number;
}
interface Contact {
phone: string;
email: string;
}
interface Student {
readonly id: number;
name: string;
personal: {
age: number;
contact: Contact;
};
address: Address;
courses: {
name: string;
duration: number;
}[];
}
const student: Student = {
id: 101,
name: "Amit",
personal: {
age: 20,
contact: {
phone: "9876543210",
email: "amit@example.com"
}
},
address: {
city: "Aurangabad",
state: "Bihar",
pin: 824101
},
courses: [
{
name: "TypeScript",
duration: 3
},
{
name: "React Native",
duration: 6
}
]
};
console.log(
student.name
);
console.log(
student.personal.contact.phone
);
console.log(
student.address.city
);
console.log(
student.courses[0].name
);
Nested objects allow TypeScript to describe complex and organized data structures.
interface Student {
name: string;
address: {
city: string;
pin: number;
};
}
You can combine nested objects with interfaces, optional properties, readonly properties, arrays, functions, and other TypeScript features.
Question:
How do you access the city property of the following
nested object?
student.address.city