Skip to content

Enhancement: [prefer-optional-chain] Also rewrite if (x) x.something() #6309

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

Open
4 tasks done
fregante opened this issue Jan 8, 2023 · 5 comments
Open
4 tasks done
Labels
accepting prs Go ahead, send a pull request that resolves this issue enhancement: plugin rule option New rule option for an existing eslint-plugin rule package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin

Comments

@fregante
Copy link
Contributor

fregante commented Jan 8, 2023

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

My proposal is suitable for this project

  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Link to the rule's documentation

https://typescript-eslint.io/rules/prefer-optional-chain/

Description

The rule apparently only tries to prevent a && a.b, but another way to write that is if (a) a.b

Could the rule be updated to include if conditions?

Fail

if (callback) {
  callback();
}

if (list) {
  list.push(item);
}

Pass

callback?.();

list?.push(item);

// Optional chaining doesn't apply here
if (callback) {
  callbacks.push(callback);
}

Additional Info

No response

@fregante fregante added enhancement: plugin rule option New rule option for an existing eslint-plugin rule package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for team members to take a look labels Jan 8, 2023
@bradzacher
Copy link
Member

bradzacher commented Jan 8, 2023

This would be a great addition - it's a really common pattern that could be simplified. Though I can see this being an option - I can see some people might prefer the more verbose form.

Though it's worth noting that this would be non-trivial to build and handle all the cases.

@bradzacher bradzacher added accepting prs Go ahead, send a pull request that resolves this issue and removed triage Waiting for team members to take a look labels Jan 8, 2023
@Josh-Cena
Copy link
Member

What about multiple statements?

if (foo) {
  foo.bar();
  foo.baz();
}

It could be simplified but some would see it as "non-performant".

@fregante
Copy link
Contributor Author

fregante commented Oct 2, 2023

I think that it'd make sense as an auto fix of a single statement, but not multiple. If anything, if I see this I'd want it fixed in the opposite direction (separate rule):

o?.foo()
o?.bar()
o?.baz()

@JoshuaKGoldberg
Copy link
Member

It's not technically safe to auto-fix multiple statements. An earlier statement might modify the value being optionally chained.

https://typescript-eslint.io/play/#ts=5.2.2&fileType=.tsx&code=JYOwLgpgTgZghgYwgAgGIHt0HF1gQCzmQG8AoZZAIzigAoBKALmQDd1gATAbnKrgC8GzNpx4BfUqQA2EMMhiZmGbLgJEAPsgCuIDhBigIHZAF4SvanXrmKFBelPbd%2Bw915iANBYEMSyCRKkAPRByABC%2BuhQEIykwDDItPbWZHaYAHSWDDxp6Jk%2B9OKSIcgAgjCQUKT2APz5Vjy1%2BYKFQA&eslintrc=N4KABGBEBOCuA2BTAzpAXGYBfEWg&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false

  • Before: Cannot read properties of undefined (reading 'baz')
  • After: no crash

One shudders to imagine the use case for wanting to preserve the thrown error, but it does technically change code behavior.

@kirkwaiblinger
Copy link
Member

It's not technically safe....

See also: ill-behaved getters 😁

I agree with not rewriting multistatement optional chains, but, I think that in general we should follow TS's lead in control flow modelling, where a function call, or, god forbid, a member access, does not invalidate narrowing.

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: plugin rule option New rule option for an existing eslint-plugin rule package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin
Projects
None yet
Development

No branches or pull requests

5 participants