Skip to content

Object.fromEntries loses all types on the key #49305

Closed

Description

@hfhchan

lib Update Request

Configuration Check

My compilation target is es2020 and my lib is ES2020.

Missing / Incorrect Definition

fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T };

should be

fromEntries<K extends PropertyKey, T = any>(entries: Iterable<readonly [K, T]>): { [k in K]: T };

Sample Code

enum Period {
  M1 = '1m',
  M3 = '3m',
  M6 = '6m',
  Y1 = '1y',
  Y3 = '3y',
  Y5 = '5y',
  Y10 = '10y',
}

const list: [Period, moment.Moment][] = [
  [Period.M1, moment().subtract(1, 'month')],
  [Period.M3, moment().subtract(3, 'months')],
  [Period.M6, moment().subtract(6, 'months')],
  [Period.Y1, moment().subtract(1, 'year')],
  [Period.Y3, moment().subtract(3, 'years')],
  [Period.Y5, moment().subtract(5, 'years')],
  [Period.Y10, moment().subtract(10, 'years')],
];

const object: { [k in Period]: moment.Moment } = Object.fromEntries(list);

Returns error for object:

Type '{ [k: string]: Moment; }' is missing the following properties from type '{ "1m": Moment; "3m": Moment; "6m": Moment; "1y": Moment; "3y": Moment; "5y": Moment; "10y": Moment; }': "1m", "3m", "6m", "1y", and 3 more.ts(2740)

Documentation Link

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

Notes

I've read the soundness issues discussion on Object.keys(), but I'm not seeing how that should/would apply to Object.fromEntries().

Say if I am passing a [A, B][] into Object.fromEntries() where A is union of a class C and another enum D, I am going to get C.toString() | D. I am already hitting fromEntries(entries: Iterable<readonly any[]>): any; instead.

Activity

  1. hfhchan commented on May 30, 2022

    @hfhchan
    Author

    See also: #37457 (comment)

    I just noted that this doesn't work because it's possible to omit a particular row in list, but the resulting type for Object.fromEntries() would generate an object that has all possible Periods as keys.

    Apparently

    fromEntries<K extends PropertyKey, T = any>(entries: Iterable<readonly [K, T]>): { [k: K]: T };

    doesn't work either

  2. hfhchan commented on May 30, 2022

    @hfhchan
    Author

    Essentially a duplicate of #35745 but that issue has been closed without resolution.

  3. RyanCavanaugh commented on May 31, 2022

    @RyanCavanaugh
    Member

    It wouldn't be correct to do this, because the type of an array tells you want might be in it, not what is in it. For example, list could be entirely empty, which would make object's value be { }, despite the type of object saying that it had a M1 property.

  4. typescript-bot commented on Jun 2, 2022

    @typescript-bot
    Contributor

    This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  5. lbfalvy commented on Jan 9, 2024

    @lbfalvy

    Why not type it as fromEntries<K, V>(entries: [K, V][]): {[k: K]?: V}?

  6. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions