Skip to content

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

@niieani

Description

@niieani

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 (#35745, #49305, #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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    SuggestionAn idea for TypeScriptToo ComplexAn issue which adding support for may be too complex for the value it adds

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions