-
Notifications
You must be signed in to change notification settings - Fork 885
Rule prefer-object-spread should not work when the first argument of Object.assign is not {} #3212
Comments
While I agree that your code is valid, the rule is still right in this case. You can simply convert your code as follows: const values = [2, 3, 4, 5]
const obj = values.reduce(
(o, v, i) => ({...o, [i]: v}),
{},
) It yields the same result. In some other cases it even provides better type inference and checking. That's why the rule suggests object spread in the first place. Regarding your feature request there are two possible options:
|
If we eventually will merge all properties, why we have to spread properties out? Moreover, if we wanna try such a meta programming: const o = {
a: 42
}
Object.defineProperty(o, 'a', {
set(value) {
console.log(value)
}
})
// A
const oo = Object.assign(o, { a: 7 })
// B
const ooo = Object.assign({}, o, { a: 7 })
// C
const oooo = { ...o, ...{ a: 7 }} Object.assign will trigger the setter and spread operator won't. Statement A print the '7', B and C have the same behavior. I think C shouldn't be a replacement for A but B. |
It seems like there are two things to consider:
|
Since var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };
var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed.
if (o1.b === 2) {
// this would no longer run if Object.assign is changed to `{...o1, ...o2, ...o3}`?
} If that's correct, I definitely think that the rule should only trigger when the first argument is a literal. In fact this could be considered a bug. |
It seems there is a bug with auto-fixing Object.assign, e.g.:
which will return Will be autofixed as:
which will return |
I agree that the rule is a bit aggressive right now. It applies unsafe auto fixes (related: #2625). I agree with @ajafff's suggestion of
This would align with the ESLint rule. The new rule option could be called |
One more scenario when rule works incorrect class Foo {
handleBar() {
console.log('bar handled');
}
}
const foo = new Foo();
const bar: any = Object.assign(foo, {prop: 'ok'}); // <-- tslint suggest to replace with spread but it dramatically changes semantic
bar.handleBar(); |
It's definitely a bug, not an enhancement. Please change the label.
@adidahiya How exactly would it align? The ESLint rule doesn't have any options. |
I'm suggesting that the default behavior of the rule (the proposed "basic" check) should work the same as the ESLint rule. not talking about configuration there |
|
💀 It's time! 💀TSLint is deprecated and no longer accepting pull requests other than security fixes. See #4534. ☠️ 👋 It was a pleasure open sourcing with you! |
🤖 Beep boop! 👉 TSLint is deprecated 👈 (#4534) and you should switch to typescript-eslint! 🤖 🔒 This issue is being locked to prevent further unnecessary discussions. Thank you! 👋 |
Bug Report
TypeScript code being linted
with
tslint.json
configuration:Actual behavior
Expected behavior
I actually want assign properties to the first argument, I want this side effects, it is common in reducing. The reasonable tips appearing is using
Object.assign({}, o1, o2)
, it should be suggested to using spread instead of. What I'm using is the Object.assign designed for.The text was updated successfully, but these errors were encountered: