Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

typescript

If I wanted to programatically assign a property to an object in Javascript, I would do it like this:

var obj = {}; obj.prop = "value"; 

But in TypeScript, this generates an error:

The property 'prop' does not exist on value of type '{}'

How am I supposed to assign any new property to an object in TypeScript?

like image 304
Peter Olson Avatar asked Oct 03 '12 14:10

Peter Olson


People also ask

How do you add dynamic properties to object TypeScript?

Use an index signature to dynamically add properties to an object, e.g. const obj: {[key: string]: any} = {} . Index signatures are used when we don't know all of the names of a type's properties and the type of their values ahead of time.

How do you assign a value to an object in TypeScript?

To use the Object. assign() method in TypeScript, pass a target object as the first parameter to the method and one or more source objects, e.g. const result = Object. assign({}, obj1, obj2) . The method will copy the properties from the source objects to the target object.


2 Answers

Index types

It is possible to denote obj as any, but that defeats the whole purpose of using typescript. obj = {} implies obj is an Object. Marking it as any makes no sense. To accomplish the desired consistency an interface could be defined as follows.

interface LooseObject {     [key: string]: any }  var obj: LooseObject = {}; 

OR to make it compact:

var obj: {[k: string]: any} = {}; 

LooseObject can accept fields with any string as key and any type as value.

obj.prop = "value"; obj.prop2 = 88; 

The real elegance of this solution is that you can include typesafe fields in the interface.

interface MyType {     typesafeProp1?: number,     requiredProp1: string,     [key: string]: any }  var obj: MyType ; obj = { requiredProp1: "foo"}; // valid obj = {} // error. 'requiredProp1' is missing obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number  obj.prop = "value"; obj.prop2 = 88; 

Record<Keys,Type> utility type

Update (August 2020): @transang brought this up in comments

Record<Keys,Type> is a Utility type in typescript. It is a much cleaner alternative for key-value pairs where property-names are not known. It's worth noting that Record<Keys,Type> is a named alias to {[k: Keys]: Type} where Keys and Type are generics. IMO, this makes it worth mentioning here

For comparison,

var obj: {[k: string]: any} = {}; 

becomes

var obj: Record<string,any> = {} 

MyType can now be defined by extending Record type

interface MyType extends Record<string,any> {     typesafeProp1?: number,     requiredProp1: string, } 

While this answers the Original question, the answer here by @GreeneCreations might give another perspective on how to approach the problem.

like image 124
Akash Avatar answered Sep 24 '22 18:09

Akash


Or all in one go:

  var obj:any = {}   obj.prop = 5; 
like image 35
Crwth Avatar answered Sep 24 '22 18:09

Crwth