Skip to content
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

Rule proposal: Prevent Object.values(...) usage with Map #6807

Open
6 tasks done
MadLittleMods opened this issue Mar 31, 2023 · 2 comments
Open
6 tasks done

Rule proposal: Prevent Object.values(...) usage with Map #6807

MadLittleMods opened this issue Mar 31, 2023 · 2 comments
Labels
accepting prs Go ahead, send a pull request that resolves this issue enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin

Comments

@MadLittleMods
Copy link

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
  • My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Description

Using Object.values(...), Object.keys(...), Object.entries(...) with a Map object is a foot-gun because it will return empty [] regardless of the map contents and is most likely a mistake. These sorts of mistakes are easy to get into during refactors. This issue is spawning from a real-life refactor mistake -> element-hq/element-web#24995 (comment)

Related StackOverflow question: https://stackoverflow.com/questions/72315392/how-to-prevent-the-mistake-of-calling-object-values-on-a-map

As @bergus mentions from the SO question, it's possible to extend Map to make a subclass that returns something with the object utilities but this seems a lot more niche compared to the big problem of running them on base Map objects. AFAICT, it's not possible to use TypeScript on its own to catch this sort of thing because practically everything inherits from Object and function arguments in TypeScript are contravariant (accepts supertypes but doesn't accept subtypes).

Fail Cases

const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);

// Rule would error for each of these usages, as using these object utilities
// on a Map will just return empty results and is probably a mistake
Object.keys(map); // -> []
Object.values(map); // -> []
Object.entries(map); // -> []

Pass Cases

const myObject = { 1: 'one', 2: 'two' };
Object.keys(myObject); // -> ['1', '2']
Object.values(myObject); // -> ['one', 'two']
Object.entries(myObject); // -> [[ 1, 'one' ],[ 2, 'two' ]]

const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]);
map.keys(); // -> ['1', '2']
map.values(); // -> ['one', 'two']
map.entries(); // -> [[ 1, 'one' ],[ 2, 'two' ]]

Additional Info

No response

@MadLittleMods MadLittleMods added enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for maintainers to take a look labels Mar 31, 2023
@Josh-Cena
Copy link
Member

This presents an interesting intersection with no-misused-in proposed in #5677. They both deal with attempting to use maps/sets as if they have object properties. I wonder how we could make the one proposed here more generalizable.

@bradzacher
Copy link
Member

Heh this request reminded me of that exact same issue! Yeah there's something interesting here because they're all related but also distinct problem sets.

Maybe a big rule like no-misused-object-likes would be a good thing?

@bradzacher bradzacher added accepting prs Go ahead, send a pull request that resolves this issue and removed triage Waiting for maintainers to take a look labels Mar 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepting prs Go ahead, send a pull request that resolves this issue enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin
Projects
None yet
Development

No branches or pull requests

3 participants