-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Add an overload to Object.fromEntries
when called with const tuples
#50379
Comments
Another failing test case const x = fromEntries([] as [["foo", 1]] | Iterable<["bar", 2]>); |
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 |
This is extremely clever, but far too complex to put into the standard library. Since this can merge in at the top of the overload list, you can still get the same behavior in userland with a custom additional lib file. |
@RyanCavanaugh thanks for taking a look. I can make an NPM library for that, sounds like the way to go, unfortunately. It would be possible to make this much simpler, if we had these two things built-in in TypeScript:
@webstrand the failing test case you mentioned is failing for a good reason - there's no way to create a predictable object from that type, so it should be handled by another overload and fallback to a less strictly typed type. And as you notice, your simplified version unfortunately isn't sound. Believe me I've spent hours trying to figure it out. |
Yes, please! |
I've finally gotten around to publishing an NPM package with the strict Object.fromEntries typings. |
Would it be OK to close this PR now? |
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 ofany
.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
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 ises2022
.Missing / Incorrect Definition
Object.fromEntries
Note
Opened by request of @sandersn in #50203.
The text was updated successfully, but these errors were encountered: