snippettypescriptCritical
How do I dynamically assign properties to an object in TypeScript?
Viewed 0 times
typescriptobjecthowpropertiesdynamicallyassign
Problem
If I wanted to programmatically assign a property to an object in Javascript, I would do it like this:
But in TypeScript, this generates an error:
The property 'prop' does not exist on value of type '{}'
How do I assign any new property to an object in TypeScript?
var obj = {};
obj.prop = "value";But in TypeScript, this generates an error:
The property 'prop' does not exist on value of type '{}'
How do I assign any new property to an object in TypeScript?
Solution
Index signatures
It is possible to denote
OR to make it compact:
The real elegance of this solution is that you can include typesafe fields in the interface.
Update (August 2020): @transang brought up the
It's worth noting that
IMO, this makes it worth mentioning here
For comparison,
becomes
While this answers the Original question, the answer here by @GreeneCreations might give another perspective on how to approach the problem.
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, using an index signatureinterface 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 utility typeUpdate (August 2020): @transang brought up the
Record utility type in commentsRecord 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 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 = {}MyType can now be defined by extending Record typeinterface MyType extends Record {
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.
Code Snippets
interface LooseObject {
[key: string]: any
}
var obj: LooseObject = {};var obj: {[k: string]: any} = {};obj.prop = "value";
obj.prop2 = 88;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;var obj: {[k: string]: any} = {};Context
Stack Overflow Q#12710905, score: 1173
Revisions (0)
No revisions yet.