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?
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.
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.
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 typeUpdate (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 thatRecord<Keys,Type>
is a named alias to{[k: Keys]: Type}
whereKeys
andType
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.
Or all in one go:
var obj:any = {} obj.prop = 5;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With