Linter · Rules
unicorn/prefer-object-from-entries
Require Object.fromEntries() to turn key-value pairs into an object
Building an object with reduce and a spread copies the whole object on every step, so the work grows with the square of the number of items. Object.fromEntries() does it in one pass and says what the code is for.
The rule reports a reduce that starts from {} or Object.create(null). The callback must be an arrow function without a block body that returns { ...result, key: value } or Object.assign(result, { key: value }). It also reports _.fromPairs() and lodash.fromPairs().
Configure
Off by default. To turn it on:
[lint.rules]
"unicorn/prefer-object-from-entries" = "error" # or "warn"
Every option, set to its default:
[lint.rules]
"unicorn/prefer-object-from-entries" = ["error", {
functions = ["_.fromPairs", "lodash.fromPairs"],
}]
Examples
Reported:
const byId = users.reduce((result, user) => ({ ...result, [user.id]: user }), {});
const ages = users.reduce((result, user) => Object.assign(result, { [user.name]: user.age }), {});
const query = _.fromPairs(pairs);
Not reported:
const byId = Object.fromEntries(users.map(user => [user.id, user]));
const ages = Object.fromEntries(users.map(user => [user.name, user.age]));
const query = Object.fromEntries(pairs);
A reduce that starts from an object with properties, or that adds more than one property per step, isn't reported:
const settings = flags.reduce((result, flag) => ({ ...result, [flag]: true }), { debug: false });
const index = users.reduce((result, user) => ({ ...result, [user.id]: user, [user.email]: user }), {});
Options
| Option | Default | What it does |
|---|---|---|
functions | ["_.fromPairs", "lodash.fromPairs"] | Functions to report when they're called with one argument. A name can have dots, like "utils.toObject". Your list replaces the default. |
const query = utils.toObject(pairs);
_.fromPairs isn't in the list anymore:
const query = _.fromPairs(pairs);