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

Non-null assertion operator whitespace allowances can create confusing conditional statements #60518

Open
jaredmcateer opened this issue Nov 16, 2024 · 2 comments · May be fixed by #60628
Open
Labels
Experience Enhancement Noncontroversial enhancements Help Wanted You can do this Suggestion An idea for TypeScript
Milestone

Comments

@jaredmcateer
Copy link

🔎 Search Terms

You can write a non-null assertion operator with whitespace after a variable name and no white space before certain keywords such as in and instanceof and the type checker doesn't fail but instead strips the operator creating the opposite condition as it appears.

To a someone not familiar with TypeScript/JavaScript key !in obj reads like if key not in obj . To them this might be if the tsc treated key !== 'a' as key == 'a'

🕗 Version & Regression Information

  • This changed between versions N/A and N/A
  • This changed in commit or PR N/A
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Common "Bugs" That Aren't Bugs
  • I was unable to test this on prior versions because N/A

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.8.0-dev.20241116#code/MYewdgzgLgBAZiEAuGBvAhgfhdATgSzAHMBfGAXjXRQHIAjdXGkgbgChRJYBrAUwE8KMGuhox0EGJ2js2+ODAAUfQQEJC8RAEo0bGFPAQQAG14A6YyCKKEIANoqAulvYk2chTcQx1XdGGBeEAUAeToAK15gKB1UPQNIE3NLayh+AAcghVsXNhIgA

💻 Code

const foo: {a?: string} = {a: 'bar'};
const key = 'a' as const;

if (key !in foo) {
  // non-null operator stripped and key exists in obj
  console.log(foo[key]);
}

if (foo !instanceof Object) {
  // non-null operator stripped and obj is Object
  console.log(typeof foo);
}

🙁 Actual behavior

The TSC stripped the non-null assertion, the operator should not be considered a non-null operator at all in this situation.

🙂 Expected behavior

I would expect a syntax error in this situation.

Additional information about the issue

This is a real problem not just hypothetical, I noticed a discussion started by a person learning typescript complaining about how their code was evaluating true regardless of the "negation operator" being used before the in keyword.

Image

@bgenia
Copy link

bgenia commented Nov 16, 2024

Typescript-eslint has a rule for this

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Nov 27, 2024

Previously looked at at #56384; I think we'd take a (correct) PR to just disallow !in and !instanceof.

(related)

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Experience Enhancement Noncontroversial enhancements labels Nov 27, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Nov 27, 2024
@RyanCavanaugh RyanCavanaugh added the Help Wanted You can do this label Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experience Enhancement Noncontroversial enhancements Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants