Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object.fromEntries loses all types on the key #49305

Closed
hfhchan opened this issue May 30, 2022 · 5 comments
Closed

Object.fromEntries loses all types on the key #49305

hfhchan opened this issue May 30, 2022 · 5 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@hfhchan
Copy link

hfhchan commented May 30, 2022

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.

@hfhchan
Copy link
Author

hfhchan commented May 30, 2022

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

@hfhchan
Copy link
Author

hfhchan commented May 30, 2022

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

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label May 31, 2022
@RyanCavanaugh
Copy link
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.

@typescript-bot
Copy link
Collaborator

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

@lbfalvy
Copy link

lbfalvy commented Jan 9, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants