Add Properties in TypeScript Based on Another Property Value

Robin
Updated on July 7, 2023

When we define types for our objects in TypeScript, we explicitly include object property types. It means you can add all the defined properties while creating your objects.

But sometimes we might want to add some properties conditionally based on another property value. Let's see an example to understand the situation.

          type Vehicle = {
    type: 'bus' | 'truck'
    wheels: number
    totalSeats?: number
    totalCargo?: number
}

const bus: Vehicle = {
    type: 'bus',
    wheels: 6,
    totalSeats: 50,
    totalCargo: 200
}
        

In this Vehicle type, I have 4 properties. The type property can be either a bus or truck and, totalSeats and totalCargo are optional properties.

I want to add totalSeats property if the value of type property is bus. If the value of type property is truck, I will add totalCargo property to my object.

But as you can see, even though I am creating a bus object, I can define both totalSeats and totalCargo properties in this object. TypeScript won't show any error.

How can you solve this problem?

In this blog post, I am going to show you how to define properties in objects depending on the value of another property.

Add Properties Conditionally Based on Another Property

To define properties conditionally, you have to combine multiple types. In the previous example, the Vehicle type has one common property which is wheels.

We need to create 2 separate types for bus and truck then add the wheel property to them.

          type Bus = {
    type: 'bus'
    totalSeats: number
}

type Truck = {
    type: 'truck'
    totalCargo: number
}

type Vehicle = {
    wheels: number
} & (Bus | Truck)

        

The Bus type represents a bus and has two properties: type, which is set to 'bus', and totalSeats, which specifies the total number of seats on the bus.

The Truck type represents a truck and has two properties: type, which is set to 'truck', and totalCargo, which indicates the total amount of cargo the truck can carry.

The Vehicle type is a combination of either a Bus or a Truck and an object that contains the wheels property.

          const bus: Vehicle = {
    type: 'bus',
    wheels: 6,
    totalSeats: 50,
}

const truck: Vehicle = {
    type: 'truck',
    wheels: 6,
    totalCargo: 200,
}
        

When we create bus and truck objects using the Vehicle type, you can't define totalCargo property if the value of type property is bus. TypeScript will show an error if you try it.

You also can't define totalSeats property in a truck type object. But the wheels property is common for both objects.

Also Read: TypeScript Type vs. Interface: Which One Should You Use?


Access Dynamic Properties Using Type Guard

As we are adding properties conditionally, we have to use type guards to access those properties. You can access type and wheels properties because objects of type Vehicle have these 2 properties.

But if you want to get the values of totalSeats and totalCargo properties, you have to check the value of type property. Because these 2 properties depend on the type property.

          const truck: Vehicle = {
    type: 'truck',
    wheels: 6,
    totalCargo: 200,
}

const vehicleInfo = (vehicle: Vehicle) => {
    if (vehicle.type === 'bus') {
        console.log(vehicle.totalSeats)
    }

    if (vehicle.type === 'truck') {
        console.log(vehicle.totalCargo)
    }
}

vehicleInfo(truck)
        

The vehicleInfor() function takes a parameter of type Vehicle. To get the value of totalSeats property, I am checking if the type property is equal to bus.

Again I am checking if the type is equal to truck to access the totalCargo property. If you don't check the type property before accessing these 2 properties, TypeScript will give an error.

Related Posts