Skip to content

Add ES2019 Object.fromEntries function - #30934

Merged
Ryan Cavanaugh (RyanCavanaugh) merged 5 commits into
microsoft:masterfrom
saschanaz:es2019-object
Apr 30, 2019
Merged

Ryan Cavanaugh (RyanCavanaugh) merged 5 commits into
microsoft:masterfrom
saschanaz:es2019-object

Conversation

@saschanaz

@saschanaz Kagami Sascha Rosylight (saschanaz) commented Apr 15, 2019 •

Copy link
Copy Markdown
Contributor

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

Kagami Sascha Rosylight (@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 :-)

@RyanCavanaugh
Ryan Cavanaugh (RyanCavanaugh) merged commit 49d6f61 into microsoft:master Apr 30, 2019
@AWare

Copy link
Copy Markdown

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 🎉
Kagami Sascha Rosylight (@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
Kagami Sascha Rosylight (saschanaz) deleted the es2019-object branch May 14, 2019 10:00
@saschanaz

Kagami Sascha Rosylight (saschanaz) commented May 14, 2019 •

Copy link
Copy Markdown
Contributor Author

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

@AnyhowStep

AnyhowStep commented Jul 3, 2019 •

Copy link
Copy Markdown
Contributor

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 (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