I have an object which has title
as string and order
as number, and then there will be dynamic number of properties of type number on it
So I tried to define it like below
appraisalGroups: Array<{
title: string,
order: number,
[key:string]: number,
}>;
and later this will be assigned like this (this is just an example in my read application there will be a loop and keys are coming from a rest api)
this.appraisalGroups[0]['mykey1'] = 5
and I got ts error
Property 'title' of type 'string' is not assignable to string index type 'number'
My question is how can I make it typed?
https://stackblitz.com/edit/angular-mzdwmn
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 define an object of objects type in TypeScript, we can use index signatures with the type set to the type for the value object. const data: { [name: string]: DataModel } = { //... }; to create a data variable of type { [name: string]: DataModel } where DataModel is an object type.
Dynamically-typed languages are those (like JavaScript) where the interpreter assigns variables a type at runtime based on the variable's value at the 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.
You are getting this because index signatures force all properties to match their return type. As stated in Typescript docs: https://www.typescriptlang.org/docs/handbook/interfaces.html
While string index signatures are a powerful way to describe the dictionary pattern, they also enforce that all properties match their return type.
An index signature is explicitly saying "whenever this object is indexed with a value of this type, it will return a value of that type".
In your example, your index signature says that "whenever this object is indexed with a string, it will return a number". However, the compiler sees that this rule can be broken because one of your properties is not a number, so it throws an error.
I'm not sure what your problem space is but if the dynamic properties all have something in common, then it might be easier to create an interface to abstract their commonalities away. How you use said interface really depends on what you want to do though.
EDIT: You could also be cheeky and take a shortcut and simply use a Union type. So instead of [key:string]: number
you do [key:string]: number | string
.
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