eslint-plugin-unicorn
eslint-plugin-unicorn copied to clipboard
Rule proposal: Named object destructuring
Description
Readability/consistency
It took me a moment to figure out what this line does: https://github.com/sindresorhus/open/blob/2ea66da8e8b20880d235447cf4c94ba275da6a5a/index.js#L307
Fail
const {[a]: b} = c;
I think we should still detect it here since I believe consistency should be sacrificed for readability (does someone remember what that 3-step or so style guide was called?).
const {d} = g;
const {[a]: b} = c;
const {f} = h;
Pass
const b = c[a];
const {d} = g;
const b = c[a];
const {f} = h;
Proposed rule name
no-unreadable-object-destructuring
Additional Info
No response
I agree, IMHO only very basic destructuring should ever be allowed, anything else is way harder to parse than the basic version.
Unicorn already has a related rule but just for arrays:
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unreadable-array-destructuring.md
👍 I think it would make sense to add a no-unreadable-object-destructuring rule.
Would be good to try to think of other anti-patterns that this rule could also catch.
The computed destructuring is readable to me, but people may get confused by some of the following cases
-
Renamed
const {a: renamed} = b -
Default values
const {a = b} =c -
Deep destructuring
const { a: { b } } = d -
Array destructuring inside object destructuring
const { a: [b] } = d
Combined all cases above
const {
[a]: {
[b]: c = d,
e: [f]
} = {}
} = g
3 and 4 are visually same, one is {b} and the other one is [b], neither one is readable 👍
Renames and default values are not super common, but they're very useful when setting defaults from options objects:
const {
enabled = true,
id,
depth = 1,
replacements = []
} = options;
Maybe combining both still isn't ideal:
const {
enabled: isEnabled = true,
id: name,
depth = 1,
replacements: array = []
} = options;
Combining it with inline types is particularly lethal, but that's another issue.
I suppose this rule should also apply to function parameters:
function foo({
[a]: {
[b]: c = d,
e: [f]
} = {}
}) {}
Renames and default values are very useful and should be allowed.
Deep restructuring should be allowed to a certain level. Maybe two levels down.
Array destructuring inside an object is pretty unreadable and should not be allowed.
Deep destructuring and default value can also confusing when the right side has multiple properties, even it's "simple".
Shorthand
const {
a = {
b,
c
}
} = d
const {
a: {
b,
c
}
} = d
const {
a: e = {
b,
c
}
} = d
Longhand
const {
a = {
b: e,
c
}
} = d
const {
a: {
b: e,
c
}
} = d
const {
a: {
b = e,
c
}
} = d