Add Any Number of Dynamic Properties to TypeScript Objects

Robin
Updated on July 9, 2023

We want to add dynamic properties in TypeScript objects when we don't know the property names beforehand. Many times we also want to determine the object keys at runtime.

There are two ways to assign any number of properties with dynamic keys in TypeScript:

  • Using index signature.
  • Using Record utility type.

In this post, you will learn how to create a TypeScript type for an object so that you can add any property to it without defining the property name explicitly.

You can also use any name for your object properties. You won't have any restrictions while creating the objects.

But there are also some drawbacks to this pattern. We will discuss everything in detail so that you can choose accordingly.

Assign Properties with Dynamic Key Using Index Signature

In TypeScript, you can add dynamic properties to objects by using index signatures. An index signature allows you to define a property name as a string or number, and its corresponding value type.

          interface MyObject {
    [key: string]: any
}

const obj: MyObject = {
    foo: "Hello"
}

obj.bar = 42

console.log(obj.foo)
// Hello

console.log(obj.bar)
// 42
        

the MyObject interface includes an index signature [key: string]: any, which means that the object can have any number of properties with string keys and values of any type.

You can then create an object obj using the MyObject interface and add properties to it dynamically by assigning values to them.

Here I am using any type for the property value to set any data as the property value. But you can use any other type like string, number, etc in here.

          type MyObject = {
    [key: string]: any
}

const obj: MyObject = {
    foo: "Hello"
}

obj.bar = 42

console.log(obj.foo)
// Hello

console.log(obj.bar)
// 42
        

You can also use the type keyword to create your type with an index signature instead of using interface if you want.

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


Add Dynamic Properties Using Record Utility Type

Using the Record utility type in TypeScript is a way to make your objects more flexible. You can add properties to it dynamically, without knowing the property names in advance.

The Record utility type takes two arguments: the type of the keys and the type of the values for those keys.

It will return a type for an object that acts like a blueprint to tell tells TypeScript how your object should look.

          type MyObject = Record<string, any>

const obj: MyObject = {
    foo: 'Hello',
}

obj.bar = 42

console.log(obj.foo)
// Hello

console.log(obj.bar)
// 42
        

In this case, I want our keys to be strings, so I use string as the first argument.

The second argument represents the type of values for those keys. Since I want to allow any type of value, I am using the any type.

The Record utility type provides a concise and clean way to define a type with an index signature. Because under the hood, it also uses the index signature.

Also Read: Add Properties in TypeScript Based on Another Property Value


Drawbacks of Declaring Dynamic Properties in TypeScript

While dynamic properties can provide flexibility in TypeScript, they also come with some drawbacks that should be considered:

  • Lack of Type Safety: When using dynamic properties, TypeScript cannot perform type-checking on those properties by default. This means that you may encounter runtime errors if you access or manipulate dynamic property that doesn't exist.
  • Lack of Support: As TypeScript doesn't know about the properties, you won't get any autocompletion support from the TypeScript compiler.
  • Reduced Readability and Maintainability: Dynamic properties can make the code less readable and harder to understand, especially when the property names and types are not known in advance.
  • Increased Potential for Bugs: Dynamic properties can introduce a higher risk of introducing bugs, as they bypass the compile-time checks and safeguards provided by TypeScript.

Because of these drawbacks, it's generally recommended to use explicit types/interfaces whenever possible. Otherwise, you have to work without any TypeScript support.

But if you have any situation where explicit types doesn't work, you can make use of dynamic properties in TypeScript object.

Also Read: Mastering Type Casting in TypeScript: A Complete Guide

Related Posts