The problem with the last attempt was that Record seemed to expect only string | number | symbol, and since TypeScript unsure what T[U] gonna be, hence it threw the error. I found that we can tell TS a little bit more about T as below
const convertListToMap = <
T extends { [key: string|number]: string | number },
U extends keyof T,
V extends keyof T
>(
list: T[],
key: U,
secondKey: V
) => {
const map = {} as Record<T[U], T[V]>;
for (const ele of list) {
map[ele[key]] = ele[secondKey];
}
return map;
};
From the above, we are telling typescript that T is gonna be an object with key of string, and the value is gonna be of type string | number, with that, TypeScript is happy with the definition Record<T[U], T[V]>
This solution works great and TS can infer correctly
const personObj = convertListToMap([{name: 'isaac', age: 17}, {name: 'john', age: 20}], 'name', 'age')
// const personObj: Record<string, number>
const languageObj = convertListToMap([{race: 'chinese', language: 'mandarin'}, {race: 'malay', language: 'melayu'}], 'race', 'language')
// const languageObj: Record<string,string>
Answer from Isaac on Stack OverflowHow to convert array to object in TypeScript?
Typescript convert array to object with specified type - Stack Overflow
Typescript: Is there a simple way to convert an array of objects of one type to another - Stack Overflow
Typescript convert object to Array - Stack Overflow
function b<K extends string>(...keys: K[]) : { [T in K]: string }
{
const init = {} as { [T in K]: string }
return keys.reduce((a, v) => ({ ...a, [v]: 'label'}), init);
}
var l = b('key1', 'key2');
console.log(l.key1, l.key2);
Maybe that's you want.
Is the array fixed to two? If yes, then probably can do the below:
interface R { battery?: B; kind?: K; } // set fields as optional
renderers.reduce((acc, renderer) => {
acc[renderer.name] = renderer;
return acc;
}, {} as R); // strong type it manually
You haven't showed enough of your code, so I'm not sure how you instantiate your classes, but in any case you can use the array map function:
class Item {
name: string;
desc: string;
meta: string
}
class ViewItem {
name: string;
desc: string;
hidden: boolean;
constructor(item: Item) {
this.name = item.name;
this.desc = item.desc;
this.hidden = false;
}
}
let arr1: Item[];
let arr2 = arr1.map(item => new ViewItem(item));
(code in playground)
Edit
This can be shorter with Object.assign:
constructor(item: Item) {
Object.assign(this, item);
}
you can do use something like this.
const newdata = olddata.map((x) => {
return { id: Number(x.id), label: x.label };
});
as the converted column will be mapped to the newdata array.
Just use bracket.
let obj = {0: "item A", 1: "item B", 2: "item C"}
console.log([obj]);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Also, there's an specific Array function for this matter: Array.of:
console.log ( Array.of ( 1 ) )
Run code snippetEdit code snippet Hide Results Copy to answer Expand
This is more functional-friendly:
const pipe = funs => x => funs.reduce( ( r, fun ) => fun ( r ), x )
const append = x => array => [ ...array, x ]
const sum = values => values.reduce ( ( r, value ) => value + r )
const result = pipe ( [
Array.of,
append ( 2 ),
sum
] ) ( 1 )
console.log ( result )
Run code snippetEdit code snippet Hide Results Copy to answer Expand