eslint-plugin-unicorn icon indicating copy to clipboard operation
eslint-plugin-unicorn copied to clipboard

Rule proposal: Named object destructuring

Open Richienb opened this issue 1 year ago • 7 comments

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

Richienb avatar Jul 16 '24 06:07 Richienb

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

fregante avatar Jul 25 '24 07:07 fregante

👍 I think it would make sense to add a no-unreadable-object-destructuring rule.

sindresorhus avatar Jul 25 '24 12:07 sindresorhus

Would be good to try to think of other anti-patterns that this rule could also catch.

sindresorhus avatar Jul 25 '24 12:07 sindresorhus

The computed destructuring is readable to me, but people may get confused by some of the following cases

  1. Renamed

    const  {a: renamed} = b
    
  2. Default values

    const {a = b} =c
    
  3. Deep destructuring

    const {
    	a: {
    		b
    	}
    } = d
    
  4. Array destructuring inside object destructuring

    const {
    	a: [b]
    } = d
    

Combined all cases above

const {
	[a]: {
		[b]: c = d,
		e: [f]
	} = {}
} = g

fisker avatar Aug 01 '24 09:08 fisker

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]
	} = {}
}) {}

fregante avatar Aug 01 '24 10:08 fregante

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.

sindresorhus avatar Aug 01 '24 10:08 sindresorhus

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

fisker avatar Aug 01 '24 11:08 fisker