How do I dynamically assign properties to an object in TypeScript?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In TypeScript, dynamically assigning properties is easy in JavaScript terms and constrained in type-system terms. The main question is not “Can I add a property at runtime?” because you can. The real question is how much static type safety you want while doing it.
The Simplest Option: an Index Signature
If the object really is a dynamic key-value bag, give it an index signature.
This tells TypeScript that any string key is allowed and that every value must be a string.
That is usually the best answer when the dynamic nature is part of the design rather than a temporary workaround.
Use Record for a Similar Pattern
Record is a utility type that expresses the same idea more compactly.
Record<string, number> is often easier to read than a custom interface when the type is simple.
Add Properties to Objects with Known Fields
Sometimes the object has a few required properties and also allows additional ones. In that case, combine fixed properties with an index signature.
This keeps the known fields typed while still allowing extra dynamic properties.
Use any Only When You Truly Want No Checking
You can always disable type safety by using any.
This works, but it throws away the main benefit of TypeScript. It should usually be the last resort, not the first choice.
Constrain Dynamic Keys with a Union
If the set of allowed keys is dynamic at runtime but still known at design time, use a key union rather than a fully open index signature.
This is safer because TypeScript rejects unsupported keys.
Build Objects Incrementally
When object properties are assembled in steps, Partial<T> is often useful.
This pattern is convenient, but the final cast should be used carefully. It assumes you really did populate all required fields.
Computed Property Names Still Need Compatible Types
Dynamic property names also work with normal objects as long as the type allows them.
The runtime behavior is ordinary JavaScript. The only TypeScript requirement is that the object's type admits that key/value pattern.
Pick the Type to Match the Real Shape
A good rule is:
- use fixed interfaces when the object shape is truly known
- use
Recordor an index signature for key-value maps - use
Partial<T>for stepwise construction - avoid
anyunless the data is genuinely untyped and temporary
The cleaner the type matches the real object behavior, the fewer assertions and workarounds you need later.
Common Pitfalls
A common mistake is creating {} and then assigning arbitrary properties without giving the object a type that allows those keys. TypeScript then correctly reports an error.
Another mistake is using any for convenience and losing all type checking across the rest of the code path.
Developers also often use an open Record<string, any> when the keys are actually known and could have been modeled more safely with a union or interface.
Finally, Partial<T> is helpful for incremental construction, but it does not guarantee all required fields are eventually present unless you validate before final use.
Summary
- Dynamic property assignment is allowed in TypeScript when the type says it is allowed.
- Use an index signature or
Recordfor true key-value maps. - Combine fixed fields with an index signature when the object has both known and dynamic properties.
- Use
Partial<T>for staged object construction. - Prefer the most specific safe type instead of reaching for
anyimmediately.

