How to Assign Types To Nested Objects In TypeScript

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.

Manik's photo
Manik
ยทNov 2, 2022ยท

4 min read

Subscribe to our newsletter and never miss any upcoming articles

Table of contents

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 ๐Ÿ‘.

ย 
Share this