How to Assign Types To Nested Objects In TypeScript
A complete guide on best practices and how to add type definitions to objects and nest objects in TypeScript.
Objects are what you are dealing with working as a JavaScript developer, and needless to say, that holds true for TypeScript as well. TypeScript provides you with multiple ways to define type definitions for object properties. We'll look at a couple of them throughout this post, starting with simple examples and moving on to some advanced type definitions.
Using the type
Keyword
Object properties can be assigned type definitions using the type
keyword in TypeScript. This is the easiest and preferred method to assign type definitions when dealing with simple objects. Here is an example of an Airplane
type and an airplane
object.
// Defining Airplane Type
type Airplane = {
model: string;
flightNumber: string;
timeOfDeparture: Date;
timeOfArrival: Date;
};
// Creating airplane Object
const airplane: Airplane = {
model: "Airbus A380",
flightNumber: "A2201",
timeOfDeparture: new Date(),
timeOfArrival: new Date(),
};
Nested Objects
If your object has a nested object, you can nest the type definitions using the type keyword itself. Here is an example of a nested object called caterer
inside the Airplane
type definition.
type Airplane = {
model: string;
flightNumber: string;
timeOfDeparture: Date;
timeOfArrival: Date;
caterer: {
name: string;
address: string;
phone: number;
};
};
const airplane: Airplane = {
model: "Airbus A380",
flightNumber: "A2201",
timeOfDeparture: new Date(),
timeOfArrival: new Date(),
caterer: {
name: "Special Food Ltd",
address: "484, Some Street, New York",
phone: 1452125,
},
};
Abstracting Nested Objects Into Separate Types
If you have large objects defining nested type definitions can become cumbersome. In such a case, you can define a separate Caterer
type for the nested object. This will also abstract away the Caterer
type from the Airplane
type, allowing you to use the Caterer
type in the other parts of your code.
type Airplane = {
model: string;
flightNumber: string;
timeOfDeparture: Date;
timeOfArrival: Date;
caterer: Caterer;
};
const airplane: Airplane = {
model: "Airbus A380",
flightNumber: "A2201",
timeOfDeparture: new Date(),
timeOfArrival: new Date(),
caterer: {
name: "Special Food Ltd",
address: "484, Some Street, New York",
phone: 1452125,
},
};
Using Index Signatures With Nested Objects
Index signatures can be used when you are unsure of how many properties an object will have but you are sure of the type of properties of an object. We can define another type called Seat
, which can be the details of the passenger traveling on each seat of the Airplane
type. We can use index signature to assign string type to all seat properties.
type Caterer = {
name: string;
address: string;
phone: number;
};
type Seat = {
[key: string]: string;
};
type Airplane = {
model: string;
flightNumber: string;
timeOfDeparture: Date;
timeOfArrival: Date;
caterer: {
name: string;
address: string;
phone: number;
};
seats: Seat[];
};
const airplane: Airplane = {
model: "Airbus A380",
flightNumber: "A2201",
timeOfDeparture: new Date(),
timeOfArrival: new Date(),
caterer: {
name: "Special Food Ltd",
address: "484, Some Street, New York",
phone: 1452125,
},
seats: [
{
name: "Mark Allen",
number: "A3",
},
{
name: "John Doe",
number: "B5",
},
],
};
Interfaces to Assign Types to Object Properties
If you need to create classes to generate objects, using interfaces
instead of the type keyword would be a better option. Here is an example of an airplane
object created using the Airplane
class, which extends the IAirplane
interface.
interface IAirplane {
model: string;
flightNumber: string;
timeOfDeparture: Date;
timeOfArrival: Date;
}
class Airplane implements IAirplane {
public model = "Airbus A380";
public flightNumber = "A2201";
public timeOfArrival = new Date();
public timeOfDeparture = new Date();
}
const airplane: Airplane = new Airplane();
Nested Objects Using Interfaces
Just like we used the type
keyword, interfaces
can also be used to strictly type nested objects with classes.
interface ICaterer {
name: string;
address: string;
phone: number;
}
interface ISeat {
name: string;
number: string;
}
interface IAirplane {
model: string;
flightNumber: string;
timeOfDeparture: Date;
timeOfArrival: Date;
}
class Caterer implements ICaterer {
public name = "Special Food Ltd";
public address = "484, Some Street, New York";
public phone = 1452125;
}
class Seat implements ISeat {
public name = "John Doe";
public number = "A3";
}
class Airplane implements IAirplane {
public model = "Airbus A380";
public flightNumber = "A2201";
public timeOfArrival = new Date();
public timeOfDeparture = new Date();
public caterer = new Caterer();
public seats = [new Seat()];
}
const airplane: Airplane = new Airplane();
What Can You Do Next ๐๐
If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for software developers. You can also follow me on Hashnode; my profile handle - Cloudaffle. Leave a like if you liked the article; it keeps my motivation high ๐.