Logo

How do I dynamically assign properties to an object in TypeScript?

To dynamically assign properties to an object in TypeScript, you typically need one of the following:

  1. An index signature (e.g., [key: string]: any) so TypeScript knows any string key is allowed.
  2. A mapped type or Record type if you know the expected types of the values but need dynamic keys.
  3. Casting the object to any (or using a type assertion), though this bypasses type safety.

Below are common approaches in more detail.

1. Using an Index Signature

When you define an index signature, you tell TypeScript “this object can have arbitrary string keys, and the values will be of type X.” For example:

interface StringMap { [key: string]: string; } const myObj: StringMap = {}; myObj["title"] = "Hello"; myObj["description"] = "World!";
  • Now myObj can have any string key, and the value must be a string.
  • You can also make the index signature string | number | boolean, or a custom type—whatever fits your usage.

Example with Mixed Types

If you need any type for the values:

interface AnyMap { [key: string]: any; } const myObj: AnyMap = {}; myObj["title"] = "Hello"; myObj["count"] = 42; myObj["data"] = { nested: true };

You lose strong typing on the values, but you gain the ability to store anything by a dynamic key.

2. Using a Mapped Type or Record

Record<Keys, Value>

TypeScript provides a utility type called Record:

const myObj: Record<string, number> = {}; myObj["age"] = 30; // ok myObj["width"] = 100; // ok // myObj["title"] = "some string"; // Error: not a number
  • This is effectively a shorthand for { [key: string]: number }.

Custom Mapped Types

If you have a finite set of known keys but want them dynamic in some sense, you can use a mapped type. However, usually that’s for known key unions rather than arbitrary keys. If you truly have arbitrary keys, Record<string, T> or an index signature is simpler.

3. Type Assertions (Casting) / as any

If you don’t want to define an index signature or record, you can assert the object as any (or a relevant type) at the point of assignment:

const myObj = {} as any; myObj.dynamicKey = "Hello"; myObj.someOtherKey = 123;

Caution: This bypasses TypeScript’s type safety. The compiler won’t check whether keys/values are valid. It’s a quick fix for “I know what I’m doing here,” but it can hide errors.

4. Example with a Function

function addDynamicProperty(obj: { [key: string]: any }, key: string, value: any): void { obj[key] = value; } const myObj: { [key: string]: any } = {}; addDynamicProperty(myObj, "name", "Alice"); addDynamicProperty(myObj, "age", 30); console.log(myObj); // { name: 'Alice', age: 30 }
  • The function’s parameter obj has an index signature, so TypeScript allows any string key.

Choosing an Approach

  1. Index Signature: The typical approach when you have an object with truly dynamic keys. Provide the type for the values (any, string, a custom interface, etc.).
  2. Record<Keys, Value>: A good built-in type if all keys are strings (or a union of string literals) and you know the value type.
  3. Casting to any: A quick fix, but you lose type-safety.
  4. Mapped Types: More advanced scenario if you have a known set of keys but want dynamic transformation.

For everyday “store dynamic props in this object,” an index signature or Record<string, X> is usually the cleanest solution.

Final Thoughts

TypeScript’s type system is designed to avoid unstructured “add whatever property you want” usage, because it can lead to confusion in larger codebases. But sometimes dynamic objects are necessary. In those cases, you’ll want to be explicit about how you’re storing these properties—index signatures or Record are the most common ways to keep strong typing while still allowing dynamic property assignment.

Bonus: Strengthen Your JavaScript & TypeScript Core Knowledge

For a deeper dive into JavaScript fundamentals, which TypeScript builds upon, we recommend Grokking JavaScript Fundamentals. It covers:

  • Closures & prototypes
  • Async patterns
  • Practical, real-world examples

Having a solid JS base helps you wield TypeScript effectively—especially when dealing with dynamic or advanced typing scenarios.

CONTRIBUTOR
TechGrind