In case if you are interested in fast solution:
type Values<T> = T[keyof T]
type Mapper<T> = {
[Prop in keyof T]: { key: Prop, value: T[Prop] }
}
type Convert<T> = Array<Values<Mapper<T>>>
function convert<
Prop extends string,
Value extends string,
Obj extends Record<Prop, Value>
>(obj: Obj): Convert<Obj>
function convert<
Prop extends string,
Value extends string,
Obj extends Record<Prop, Value>
>(obj: Obj) {
const result: {
key: Extract<keyof Obj, string>;
value: Obj[Extract<keyof Obj, string>];
}[] = []
for (let prop in obj) {
result.push({
key: prop,
value: obj[prop]
})
}
return result
}
const result = convert({ good: 'value1', key2: 'value2', key3: 'value3' })
const first = result[0]
if (first.key === 'good') {
// {
// key: "good";
// value: "value1";
// }
first
}
Cons:
convert function creates internal result variable and mutates it. It is possible to use recursion instead of mutation result but I'm not sure this trade of worth it.
Pros
Faster than entries & map
Convert types maps type of argument to the type you want to achieve but only in type scope, whereas function maps argument in runtime scope.
If performance is not critical, you probably should stick with other solution where Object.entries is used