The Javascript code below prints { x: 1 }
:
var foo = 'x';
var a = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
console.log(a);
Similarly, I need to dynamically build in Typescript an object, in other words when I create the object i don't know what are going to be its members.
I tried this in Typescript, but it doesn't work:
let foo = 'x';
let a = {};
if (foo == 'x')
a.x = 1; // <-- transpilation fails here
else
a.y = 2; // <-- transpilation fails here
console.log(a);
The error is Property 'x' does not exist on type '{}'.
Is it possible to create objects dynamically in Typescript?
You can create custom dynamic objects by using the classes in the System. Dynamic namespace. For example, you can create an ExpandoObject and specify the members of that object at run time. You can also create your own type that inherits the DynamicObject class.
To dynamically access an object's property: Use keyof typeof obj as the type of the dynamic key, e.g. type ObjectKey = keyof typeof obj; . Use bracket notation to access the object's property, e.g. obj[myVar] .
Syntax. var object_name = { key1: “value1”, //scalar value key2: “value”, key3: function() { //functions }, key4:[“content1”, “content2”] //collection }; As shown above, an object can contain scalar values, functions and structures like arrays and tuples.
To add a property to an object in TypeScript, set the property as optional on the interface you assign to the object using a question mark. You can then add the property at a later point in time without getting a type error. Copied!
TypeScript needs to know about the fields an object will have when you declare the variable. By default the type is inferred based on what you assign to it, since you assign {}
, a
will be of a type with no properties. You can declare the type for a
to something that will suite your needs:
var foo = 'x';
var a : { x?: number; y?:number} = {}; // Both x and y are optional, hence the ?
if (foo == 'x')
a.x = 1;
else
a.y = 2;
console.log(a);
Using a: any
is also a option but you should avoid it as it turns off any checking on a
which is probably not what you want since the whole point of typescript is to check as much as possible. I would avoid any
unless you don't know both the type of values and the key names.
If you don't know what the keys are at compile time(maybe they are based on user input or a service call) you can also use an index signature that at least will check that the type of the value is valid. For example a type that only allows number values but any key would look like this:
var foo = 'x';
var a : { [n: string]: number} = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
console.log(a);
If you do know what all the possible fields can be but you don't know which will be set, you can use a Partial<T>
, which obviates the need for you to create a new interface and put :?
everywhere, since you might want to inherit from a type / interface whose properties are not all optional:
interface A {
x: number;
y: number;
z: string;
}
let foo = 'x';
let a: Partial<A> = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
If you do not know ahead of time what any of the fields can be, since TypeScript only exists ahead of time (in the compilation phase), another option is to declare it as an any
type.
let foo = 'x';
let a: any = {};
if (foo == 'x')
a.x = 1;
else
a.y = 2;
This is rarely a desirable approach to take, however, because it defeats the purpose of using TypeScript to beign with as it completely disables type-checking.
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