Reputation: 113
I want to add an extra property to an array, but I get trouble with declaring it.
small part
const arr: string[] & {key: number} = ['123'];//ts error Property 'key' is missing
arr.key = 10;
large part
I need to group arr by index then sort it by value
add an index to array property will be a convenience if using Object.values but not Object.entries. I know there are many approaches to do this, but I think it's much easier if I am using plain js
type Arr = {index: number, value: number};
const arr:Arr[] = []
arr.push({
index: 10,
value: 2
})
arr.push({
index: 10,
value: 1
})
arr.push({
index: 10,
value: 3
});
arr.push({
index: 20,
value: 100
});
arr.push({
index: 20,
value: 50
});
arr.reduce<Record<string, Arr[] & {index: number}>>((prev, curr) => {
if(!prev[curr.index]){
prev[curr.index] = [];//ts error Property missing
prev[curr.index].index = curr.index;
}
prev[curr.index].push(curr);
prev[curr.index].sort((a,b) => a.value - b.value);//or some insertion sort algorithm.
return prev;
},{})
Upvotes: 6
Views: 4163
Reputation: 2270
Please consider the accepted answer instead.
In your small part example, the type declaration string[] & {key: number}
can never be satisfied because an array of strings cannot be the same as an object with key property.
Concerning your large part example, what exactly are you trying to achieve? If you say you want to group an array by an index, and then sort it by value, do you mean that the index is kind of your primary sort criterion and value the secondary criterion? In that case, I'd suppose you write your own sorting function that takes both values into account. You'll find an example in this Stackoverflow thread.
Upvotes: 1
Reputation: 249506
An array literal can't by itself satisfy the intersection, the simplest way you could do it is to use Object.assign
which returns an intersection of its arguments:
const arr: string[] & {key: number} = Object.assign(['123'], {
key: 10
});
And in your bigger example, the same could be used:
arr.reduce<Record<string, Arr[] & {index: number}>>((prev, curr) => {
if(!prev[curr.index]){
prev[curr.index] = Object.assign([], {
index: curr.index
})
}
prev[curr.index].push(curr);
prev[curr.index].sort((a,b) => a.value - b.value);//or some insertion sort algorithm.
return prev;
},{})
Upvotes: 10