question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add an overload to `Object.fromEntries` when called with const tuples

See original GitHub issue

lib Update Request

Object.fromEntries as is declared today results in a loss of key names and a unionization of all values, or a complete loss of information and type of any. This change would make it so that it is possible to create strict objects — from const tuples only.

Note that the usage of fromEntries with Arrays and non-readonly tuples cannot be made sound, so this issue only discusses the narrow case of const tuples.

Sample Code

const obj1 = Object.fromEntries([
  ['1', 2],
  ['3', 4],
] as const)
// this should result in an object of type: {1: 2, 3: 4}, but results instead in: { [k: string]: 2 | 4 }

const obj2 = Object.fromEntries([
  ['1', 2],
  ['3', '4'],
] as const)

// should result in an object of type: {1: 2, 3: '4'}, but results in: any

The how & example

This could be achieved by adding a new overload to Object.fromEntries in the case it is called with const tuples only. This distinction is vital, because not distinguishing between Arrays, tuples and const tuples would make this change unsound. Only properties of a readonly tuple are guaranteed to be there at runtime, since they cannot be reassigned.

Here’s a working proof-of-concept playground that should be sound in all cases, including the edge case of using a union type for the key.

The type is somewhat complex right now, so it would be great if we could somehow simplify it. Suggestions are welcome.

Related issues were previously closed, because the change would have been unsound without guarding for const tuples only (https://github.com/microsoft/TypeScript/issues/35745, https://github.com/microsoft/TypeScript/issues/49305, https://github.com/microsoft/TypeScript/issues/43332). Here however, the discussion is around const tuples only.

Configuration Check

My compilation target is es2022 and my lib is es2022.

Missing / Incorrect Definition

  • Object.fromEntries

Note

Opened by request of @sandersn in #50203.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
webstrandcommented, Aug 24, 2022

I really would rather avoid a conditional return type, at least not as the last overload. By supporting a reduced, but still improved, set of features I think this is better:

// Most generally useful
declare function fromEntries<T extends readonly [PropertyKey, unknown]>(
  entries: Iterable<T>
): { [P in T as P[0]]?: P[1] }

// Support wonky union types like `[["foo", 1]] | Iterable<["bar", 2]>`
declare function fromEntries<K extends PropertyKey, V>(
  entries: Iterable<readonly [K, V]>
): { [_ in K]?: V }

// For people destructuring `fromEntries`
declare function fromEntries(entries: Iterable<readonly [PropertyKey, unknown]>): { [key: PropertyKey]: unknown }

I just noticed that this breaks the obj2_fromMixed case

1reaction
webstrandcommented, Aug 24, 2022

Another failing test case

const x = fromEntries([] as [["foo", 1]] | Iterable<["bar", 2]>);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Why Object.fromEntries does not accept array of tuple?
The first produces a new array based on the contents of the callback (or what is often called "closure" in Swift); while the...
Read more >
How to add types for Object.fromEntries - DEV Community ‍ ‍
Step by step tutorial on how to create a proper type for Object.fromEntries() which can work with tuples and read-only data structures.
Read more >
Documentation - TypeScript 4.0
Consider a function in JavaScript called concat that takes two array or tuple types and concatenates them together to make a new array....
Read more >
Issues · microsoft/TypeScript · GitHub
Allow extra fields in object literals if they are used in methods on the object Awaiting More Feedback This means we'd like ......
Read more >
TSConfig Reference - TypeScript
@filename: card.js export const defaultCardDeck = "Heart"; ... This flag can be used as a way to incrementally add TypeScript files into JS...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found