Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get typed Object.entries() and Object.fromEntries in Typescript?

When I use Object.fromEntries(entries) or Object.entires(obj) in typescript for my typed/const entries arrays or objt objects, I am losing the types to any or a broad type.

I can manually assign generic types (e.g. Record<string, number>) in some cases, but setting types of each pair/key is tedious.

Here is an example of what I want.

Typed Object.fromEntries(entries)

const myArrayOfPairs = [["a", 5], ["b", "hello"], ["c", false]] as const;

// The type of the following is "any"
const myTypelessObject = Object.fromEntries(myArrayOfPairs);

// I want the type of this one to be: { a: 5; b: "hello"; c: false; }
const myTypedObject = createTypedObjectFromEntries(myArrayOfPairs); 

Typed Object.entries(obj)

const myOldObject = {
    x: 6,
    y: "apple",
    z: true
};

// The type of the following is [string, string | number | boolean][]
const myEntries = Object.entries(myOldObject);

// I want the type of this one to be more specific.
// i.e.: (["x", number] | ["y", string] | ["z", boolean])[]
const myTypedEntries = getTypedObjectEntries(myOldObject);
like image 585
Aidin Avatar asked Sep 11 '25 03:09

Aidin


1 Answers

This is now easier to achieve on TypeScript 5 with the new const Type Parameter.

//
// Object.fromEntries
//

const typeSafeObjectFromEntries = <
  const T extends ReadonlyArray<readonly [PropertyKey, unknown]>
>(
  entries: T
): { [K in T[number] as K[0]]: K[1] } => {
  return Object.fromEntries(entries) as { [K in T[number] as K[0]]: K[1] };
};

const myObject = typeSafeObjectFromEntries([
  ["a", 5],
  ["b", "hello"],
  ["c", false],
]); // { a: 5; b: "hello"; c: false } ✅

//
// Object.entries
// (add const param for less broader types (ie. string -> "apple") -> const T extends Record<PropertyKey, unknown>)
//

const typeSafeObjectEntries = <T extends Record<PropertyKey, unknown>>(
  obj: T
): { [K in keyof T]: [K, T[K]] }[keyof T][] => {
  return Object.entries(obj) as { [K in keyof T]: [K, T[K]] }[keyof T][];
};

const myEntries = typeSafeObjectEntries({ x: 6, y: "apple", z: true });
// ["x", number] | ["y", string] | ["z", boolean])[] ✅
// with const param: (["x", 6] | ["y", "apple"] | ["z", true])[] ✅

TypeScript Playground

like image 84
ajmnz Avatar answered Sep 13 '25 16:09

ajmnz