Skip to content

Add ES2019 Object.fromEntries function#30934

Merged
RyanCavanaugh merged 5 commits intomicrosoft:masterfrom
saschanaz:es2019-object
Apr 30, 2019
Merged

Add ES2019 Object.fromEntries function#30934
RyanCavanaugh merged 5 commits intomicrosoft:masterfrom
saschanaz:es2019-object

Conversation

@saschanaz
Copy link
Copy Markdown
Contributor

@saschanaz saschanaz commented Apr 15, 2019

Fixes #30933, fixes #25999

We already have #26149 but it hasn't been active nor reached a good consensus, so this PR adds a simpler type with potential future progressive enhancement with generics.

Comment thread src/lib/es2019.object.d.ts Outdated
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries(entries: Iterable<[string | symbol, any]>): any;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be really ideal if this could produce an object where the values matched the value item in the iterable. Perhaps?:

Suggested change
fromEntries(entries: Iterable<[string | symbol, any]>): any;
fromEntries<T = unknown>(entries: Iterable<[PropertyKey, T]>): { [k in PropertyKey]: T };

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, but a bit hesitant to do unknown here as no other function in lib.d.ts uses it for its return type. Would any be sufficient or unknown be required?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since T is inferable then any is fine, but imo nothing should ever be any, only unknown or narrower :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kinda agree but I'll go any for now, for consistency here...

Comment thread src/lib/es2019.object.d.ts Outdated
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries<T = any>(entries: Iterable<[PropertyKey, T]>): { [k in PropertyKey]: T };
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

See #29721

@RyanCavanaugh
Copy link
Copy Markdown
Member

@daniel19801 DANIEL PLEASE READ! - You cannot turn off GitHub email notifications by replying with "stop" or some variant thereof; all this is doing is posting comments to GitHub threads. Please go to your GitHub profile and turn off email notifications.

@ljharb
Copy link
Copy Markdown
Contributor

ljharb commented Apr 26, 2019

@saschanaz it'd also be great if you wanted to create a DT package for https://www.npmjs.com/package/object.fromentries using these types, once this PR is merged :-)

@microsoft microsoft deleted a comment Apr 30, 2019
@RyanCavanaugh RyanCavanaugh merged commit 49d6f61 into microsoft:master Apr 30, 2019
@AWare
Copy link
Copy Markdown

AWare commented May 14, 2019

Apologies if this is the wrong place for this but I was playing with this type locally with the package. (Which has really helped me out, so massive thanks 🎉
@saschanaz)

If I have something of the form {[x: string]: A} and take it to an array and back I get {[x: string]:A; [x: number]: A}

This goes away if I make a second type parameter for fromEntries which extends PropertyKey
<K extends PropertyKey, T = any>(entries: Iterable<readonly [K, T]>): { [k in K]: T };

@saschanaz saschanaz deleted the es2019-object branch May 14, 2019 10:00
@saschanaz
Copy link
Copy Markdown
Contributor Author

saschanaz commented May 14, 2019

@AWare That suggestion looks good, you can open a new issue so that the project maintainers can start thinking about it.

@AnyhowStep
Copy link
Copy Markdown
Contributor

AnyhowStep commented Jul 3, 2019

If anyone is looking for something with more generic hacking,

Playground

type PairToObject<P extends readonly [PropertyKey, any]> = (
    P extends any ?
    {
        [k in P[0]] : P[1]
    } :
    never
);
type ToUnaryFunctionUnion<U> = (
    U extends any ?
    (arg : U) => void :
    never
);
type UnionToIntersection<U> = (
    ToUnaryFunctionUnion<U> extends (arg : infer I) => void ?
    I :
    never
);
type _<T> = T;
type Merge<T> = _<{ [k in keyof T] : T[k] }>;

declare function fromEntries<
    P extends readonly [PropertyKey, any]
> (i : Iterable<P>) : (
    /**
     * The `Merge<>` part isn't necessary.
     */
    Merge<
        UnionToIntersection<
            PairToObject<P>
        >
    >
);

declare const entries : [
    ["a", 1],
    ["b", 2]
];
/*
    OK!
    {
        a: 1;
        b: 2;
    }
*/
const x = fromEntries(entries);
/*
    OK!
    {
        a: 1;
        b: 2;
    }
*/
const y = fromEntries([
    ["a", 1],
    ["b", 2]
] as const);
/*
    NOT WHAT WE EXPECTED,

    {
        [x: string]: number;
    }

    So, the `as const` "hack" is needed
*/
const z = fromEntries([
    ["a", 1],
    ["b", 2]
]);

@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ES2019 Object.fromEntries function proposal-object-from-entries

6 participants