How to assign dynamic properties to an object in typescript

In JavaScript, you can create objects using object syntax.

var employee = {};

Then, you can assign properties dynamically.

employee.name = "john";

Accessing dynamic properties is straightforward.

console.log(employee.name); //  John

However, if you attempt the same code in TypeScript, you encounter the following error

var employee = {};
employee.name = "john";

console.log(employee.name);

It gives a below error.

Property 'name' does not exist on type '{}'.

In TypeScript, variables are typed, meaning they must have a defined type. This provides type safety at compile time to prevent errors.

So, how do you add dynamic properties to an object in TypeScript?

How to Add Dynamic Properties to an Object in TypeScript?

There are multiple ways we can do

  • Using the any type:

    Declare an object with the any type, allowing any kind of data.

    var employee: any = {};
    employee.name = "john";
    
    console.log(employee.name);
    

    You have to write code to convert from any to desired and add extra time to do it. This is not followed type safety and defeats the purpose of doing in typescript.

  • Using interface index type signature:

    Define an interface with index type signature to store key-value pairs with a specified type.

    interface Employee {
      [key: string]: any;
    }
    

    Above, the interface is declared with string keys and value types any.

    Create an object of this interface:

    var obj: Employee = {};
    

    Assign string keys with any value:

    obj.name = "Ram";
    obj.salary = 5000;
    console.log(obj); // Outputs: { "name": "Ram", "salary": 5000 }
    

    You can also use a shorter syntax for inline index signatures.

    var obj: { [k: string]: any } = {};
    obj.name = "ram";
    obj.salary = 5000;
    console.log(obj); //{ "name": "ram",  "salary": 5000}
    
  • Using the Record Type:

    TypeScript’s Record<K, V> object can store key-value pairs with specific types.

    this object can store the string key and value any type

    var emp1: Record<string, any> = {};
    emp1.name = "Ram";
    emp1.salary = 5000;
    console.log(emp1);
    
  • Extending an Interface

    This is a cleaner way of doing type safety and object inheritance. Create a base interface with common properties.

    interface BaseObject {
      id: string;
      name: string;
    }
    

    Then, extend this base interface to create new interfaces with additional properties.

    interface Employee extends BaseObject {
      salary: string;
    }
    

    Now, you can create an object of this interface and add properties.

    var emp1: Employee = {};
    emp1.name = "john";
    

    This approach offers cleaner and reusable object extension.

Conclusion

In conclusion, we explored multiple methods for adding dynamic properties to an object in TypeScript:

  • Using any type
  • Utilizing index type signature
  • Leveraging the Record type
  • Extending interfaces

Extending interfaces stands out as a preferred approach for its reusability and type safety benefits.