Skip to content

Add ES2019 Object.fromEntries function #30933

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

Closed
5 tasks done
saschanaz opened this issue Apr 15, 2019 · 12 comments · Fixed by #30934
Closed
5 tasks done

Add ES2019 Object.fromEntries function #30933

saschanaz opened this issue Apr 15, 2019 · 12 comments · Fixed by #30934
Labels
Bug A bug in TypeScript
Milestone

Comments

@saschanaz
Copy link
Contributor

Search Terms

fromEntries

Suggestion

lib: es2019 should add Object.fromEntries() type.

Use Cases

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

Examples

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Apr 16, 2019
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Apr 16, 2019
@iugo
Copy link

iugo commented Apr 24, 2019

@waynevanson
Copy link

HI Guys,

Is this live yet and if so, which version? I can't get it to find it as Property 'fromEntries' does not exist on type 'ObjectConstructor'.

What versions of TS and NODEJS should I be running to make this work?

@waynevanson
Copy link

The file is available in my node_modules under lib.es2019.object.d.ts but it won't read from it?

Any link to any issue regarding how to resolve a similar issue is welcomed.

/// <reference no-default-lib="true"/>


/// <reference lib="es2015.iterable" />

interface ObjectConstructor {
    /**
     * 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<readonly [PropertyKey, T]>): { [k in PropertyKey]: T };

    /**
     * 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<readonly any[]>): any;
}

@waynevanson
Copy link

HI Guys,

Is this live yet and if so, which version? I can't get it to find it as Property 'fromEntries' does not exist on type 'ObjectConstructor'.

What versions of TS and NODEJS should I be running to make this work?

It looks to me that in tsconfig.json, the setting to use is target: "es2019" or greater. This means it won't work in all browsers and typescrcipt does no magic to use this.

@bennypowers
Copy link

this is what I did

declare global {
  interface ObjectConstructor {
    fromEntries(xs: [string|number|symbol, any][]): object
  }
}

const fromEntries = (xs: [string|number|symbol, any][]) =>
  Object.fromEntries ? Object.fromEntries(xs) : xs.reduce((acc, [key, value]) => ({...acc, [key]: value}), {})

@tsujp
Copy link

tsujp commented Feb 17, 2020

Extending @bennypowers to sort an object similar to this:

{
  foo: 'bar',
  baz: 'boo',
  alpha: 'beta',
}

use

Object.keys(input).sort().reduce((acc, cur) => ({ ...acc, [cur]: input[cur] }), {})

@caseyhoward
Copy link

I ended up just defining my own functions for what I needed. They're pretty gross since they use any, but they get the job done for me I think:

function fromEntries<T>(entries: [keyof T, T[keyof T]][]): T {
  return entries.reduce(
    (acc, [key, value]) => ({ ...acc, [key]: value }),
    <T>{}
  );
}

function toEntries<T>(obj: T): [keyof T, T[keyof T]][] {
  const entries: [string, any][] = Object.entries(obj);
  const entriesWithKeysLookedUp: [keyof T, T[keyof T]][] = entries.map(item => {
    const keyString = item[0];
    const value = item[1];
    return [<keyof T>keyString, value];
  });
  return entriesWithKeysLookedUp;
}

All I wanted to do was map an objects values. Ended up being way more annoying than it should have been. Does anyone know a better way? It's annoying that Object.entries returns [string, T] and not a keyof type since you know the first element in each of the array elements is a keyof something and not just a string.

@MrCheater
Copy link

@caseyhoward , Hi. I have a problem with the {} construct. TypeScript 3.8.3. http://www.typescriptlang.org/v2/en/play?useDefineForClassFields=true&allowUnreachableCode=true&allowUnusedLabels=true&downlevelIteration=true&target=99

Cannot use JSX unless the '--jsx' flag is provided.(17004)
'T' only refers to a type, but is being used as a value here.(2693)
JSX element 'T' has no corresponding closing tag.(17008)

Do you know the solution?

@javiermrz
Copy link

Go into tsconfig.json, and inside compilerOptions properties search for a property named lib. Add the string "esnext" in the array. It should look something like:

"lib": ["es2018", "dom", "esnext"]

@dmorenogogoleva
Copy link

Add ["esnext"] to the lib worked for me! Thank u

@mapurba
Copy link

mapurba commented Apr 1, 2021

Hi All,
I am seeing this issue with chrome version 70 line , Angular TS
tsconfig : "lib": [ "es2018", "dom", "esnext" ]
one thing to notice the vendor js in lazy loaded as the .

with the uses of Object.fromEntries in .ts throws the same error in chrome 70 line .

case .ts : main.ts:12 TypeError: Object.fromEntries is not a function at new AppComponent (app.component.ts:15) at NodeInjectorFactory.AppComponent_Factory [as factory] (app.component.ts:18) at getNodeInjectable (core.js:5993) at instantiateRootComponent (core.js:12873)

case Vendor : VM547 vendor.js:98199 Uncaught TypeError: Object.fromEntries is not a function at Module.<anonymous> (VM547 vendor.js:98199) at i (VM547 vendor.js:98199) at push../node_modules/@ckeditor/ckeditor5-build-decoupled-document/build/ckeditor.js (VM547 vendor.js:98199) at VM547 vendor.js:98199 at VM547 vendor.js:98199 at Object../node_modules/@ckeditor/ckeditor5-build-decoupled-document/build/ckeditor.js (VM547 vendor.js:98199) at __webpack_require__ (VM542 runtime.js:85) at __webpack_require__ (VM542 runtime.js:85) at Module../src/app/shared/shared.module.ts (VM545 main.js:2147)

what is the right match so that all the dependency can be added in compile ?

but adding this to the polyfills make it work for all the cases .
import "core-js/es/object/from-entries";

ame right ?

*platform is web .

intention is to support the newer libs for older codebase dependency .

Thanks ,
Apurba M.

@sadeghmasoomi
Copy link

go to "tsconfig.json" and adding :

"lib": ["es2019"];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.