Convert Object.entries reduce to Generics type

I have the following function in TypeScript, what it does is convert an enum to an array.

function toKeyValList(e: any) {
  return Object.entries(e).reduce((acc: any, val: any[]) => {
    acc.push({ key: val[0], value: val[1] });
    return acc;
  }, []);
}

enum IncidentRecordStatus {
  IN_PROCESS = 'IN_PROCESS',
  CLOSE = 'CLOSE',
}

const list = toKeyValList(IncidentRecordStatus);

[LOG]: [{
  "key": "IN_PROCESS",
  "value": "IN_PROCESS"
}, {
  "key": "CLOSE",
  "value": "CLOSE"
}] 


I would like to convert it to a generic function without using the “any” type

I tried this way, but I get an error

export function toKeyValList<T>(e: T): T {
  return (Object.entries(e) as Array<[keyof T, T[keyof T]]>).reduce((acc, [key, value]) => {
    acc.push({ key: key, value: value });
    return acc;
  }, e as T);
}

what would be the correct way to do it?

Answer

If you want to infer return type, try to avoid mutations in TypeScript. Consider this example:

const toKeyValList = <
  Obj extends Record<string, string>
>(obj: Obj) =>
  Object
    .entries(obj)
    .reduce<{ key: string, value: string }[]>(
      (acc, [key, value]) => [...acc, { key, value }],
      []
    );

enum IncidentRecordStatus {
  IN_PROCESS = 'IN_PROCESS',
  CLOSE = 'CLOSE',
}

// {
//     key: string;
//     value: string;
// }[]
const list = toKeyValList(IncidentRecordStatus);

Playground

See my article about TS mutations