I am trying to typed the below utility function which takes in an array and return an object as below
const convertListToMap = (list, key, secondKey) => {
const map = {};
for (const ele of list) {
map[ele[key]] = ele[secondKey]
}
return map;
}
console.log(convertListToMap([{name: 'isaac', age: 17}, {name: 'john', age: 20}], 'name', 'age'));
console.log(convertListToMap([{race: 'chinese', language: 'mandarin'}, {race: 'malay', language: 'melayu'}], 'race', 'language'));
As you can tell key and secondKey is sort of dynamic, depending on the parameter list, so I guess generics is the way to go. Below is my attempt
const convertListToMap = <
T extends object,
U extends keyof T,
V extends keyof T
>(
list: T[],
key: U,
secondKey: V
) => {
const map = {} as Record<U, V>;
for (const ele of list) {
map[ele[key]] = ele[secondKey];
}
return map;
};
However, the above giving me error Type 'T[U]' cannot be used to index type 'Record<U, V>', wondering which part I've done wrong?
UPDATES
My latest attempt is to update the signature of map as below
const map = {} as Record<T[U], T[V]>;
for (const ele of list) {
map[ele[key]] = ele[secondKey];
}
return map;
With this latest attempt, value assignment to map variable is fine, but I'm getting error at Record declaration line with below error
Type 'T[U]' does not satisfy the constraint 'string | number | symbol'. Type 'T[keyof T]' is not assignable to type 'string | number | symbol'. Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'string | number | symbol'. Type 'T[string]' is not assignable to type 'string | number | symbol'. Type 'T[string]' is not assignable to type 'symbol'. Type 'T[keyof T]' is not assignable to type 'symbol'. Type 'T[U]' is not assignable to type 'symbol'. Type 'T[keyof T]' is not assignable to type 'symbol'. Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'symbol'. Type 'T[string]' is not assignable to type 'symbol'.ts(2344)
mapis not typeRecord<U, V>since you're putting in the values fromT, not the keysconst map = {} as Record<T[U], T[V]>;but it doesn't work either haha