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

Checking for void in logical operations #7256

Closed
tomitrescak opened this issue Feb 26, 2016 · 14 comments
Closed

Checking for void in logical operations #7256

tomitrescak opened this issue Feb 26, 2016 · 14 comments
Assignees
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@tomitrescak
Copy link

In many cases it is not desirable to allow comparison with undefined. Is it somehow enforceable that this will be detected during compilation?

function a() { }

if (a()) { } // this should throw error

I guess this is by design not available.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Feb 26, 2016
@RyanCavanaugh
Copy link
Member

It's certainly very suspicious. We can look at how much code this might break.

@DanielRosenwasser DanielRosenwasser self-assigned this Feb 26, 2016
@DanielRosenwasser
Copy link
Member

Disallowing void from the LHS of a ||, &&, and conditionals, we catch this somewhat inappropriate code in the compiler.

12983                 checkFunctionOrMethodDeclaration(node) || checkGrammarForGenerator(node);
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/compiler/checker.ts(12983,17): error TS5063: The left-hand side of a '||' expression cannot have type 'void'.

Running tests now.

@tomitrescak
Copy link
Author

Oh wow, that would save me from the world of problems! Please let me know whether this will make it into "next" version. I guess this can be configurable with a parameter in tsconfig.

@zpdDG4gta8XKpMCd
Copy link

can we instead add a flag that prohibits non-boolean expressions where a boolean is expected? #7306

@tomitrescak
Copy link
Author

@DanielRosenwasser would you be able to share with us, what is the result? Will this (flag) make it to the compiler? Thanks!

@adidahiya
Copy link
Contributor

This would be pretty great to have in the compiler. Linking to our TSLint issue tracking this: palantir/tslint#253

@DanielRosenwasser
Copy link
Member

@tomitrescak sorry, I've been sidetracked on other things. The team will need to review whether we're certain that it's a net positive as well. In the mean time, my pull request can be found at #7261. I don't think there's a ton of controversial stuff in it. Feel free to try it out, review it, and get back to me.

@RyanCavanaugh
Copy link
Member

👍 great idea

@zpdDG4gta8XKpMCd
Copy link

sometimes I really hard to follow your reasoning

void method/functions return undefined, returning undefined is a pretty normal thing in idiomatic JavaScript because it is one of the few types coerces to a false value naturally, so it seems an overkill to ban it on a this can never happen premise

a more vicious problem is when you had a boolean value in a condition expression, but after refactoring it turned, say, into a lazy boolean () => boolean

can we flag it?

oh sure, tslint (well actually something more capable that that) to the rescue, I know, I know

@RyanCavanaugh
Copy link
Member

it is one of the few types coerces to a false value naturally, so it seems an overkill to ban it on a this can never happen premise

I don't understand this logic. The point is that a conditional on a known-falsy value is almost certainly a bug because it creates either unreachable code, or code that appears conditionally-executed when it is in fact unconditionally executed.

On the flipside, the problem is that there's lots of idiomatic code that does stuff like this:

// x.filterFunc: () => boolean
if (x.filterFunc) {
  arr = arr.filter(x.filterFunc);
}

Certainly one can have the opinion that it would be more correct to write if (x != filterFunc) { but that's ultimately just a matter of style.

@zpdDG4gta8XKpMCd
Copy link

what about void returning overloads mixed with non voids ones?

speaking of style, it's not sbout style at all, the problem is (seen it a
few times myself) that the code with a boolean expression in the condition
of the if statement during refactoring accidentally turns into something
else (a non boolean expression), and after it still type checks, because
non boolean expressions are totally welcome there, thus a bug is planted
that can't be found by the compiler

before

var isFirst:boolean;
if (isFirst) {
// reachable
}

after refactoring

var isFirst : () => boolean;
if (!isFirst) {
// unreachable
}

On Mar 14, 2016 10:59 PM, "Ryan Cavanaugh" notifications@github.com wrote:

it is one of the few types coerces to a false value naturally, so it seems
an overkill to ban it on a this can never happen premise

I don't understand this logic. The point is that a conditional on a
known-false value is almost certainly a bug because it creates either
unreachable code, or code that appears conditionally-executed when it is in
fact unconditionally executed.

On the flipside, the problem is that there's lots of idiomatic code that
does stuff like this:

// x.filterFunc: () => booleanif (x.filterFunc) {
arr = arr.filter(x.filterFunc);
}

Certainly one can have the opinion that it would be more correct to
write if (x != filterFunc) { but that's ultimately just a matter of style.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub:
#7256 (comment)

@RyanCavanaugh
Copy link
Member

I totally understand how you could find yourself in that state. I've been there myself.

At the same time, there is a lot of code that is in that state on purpose that does not have any bugs.

@RyanCavanaugh RyanCavanaugh added this to the Community milestone Sep 16, 2016
@RyanCavanaugh RyanCavanaugh added the Good First Issue Well scoped, documented and has the green light label Sep 16, 2016
@dead-claudia
Copy link

I'll note that it's also very frequent that people (like me) use numbers in conditionals. It's not that uncommon for me to do something like this:

if (list.length) {
    // list isn't empty, let's do something with it.
}

So I personally agree that it's best left to a linter.

@RyanCavanaugh RyanCavanaugh added the Committed The team has roadmapped this issue label Aug 7, 2018
@RyanCavanaugh RyanCavanaugh self-assigned this Aug 7, 2018
@RyanCavanaugh RyanCavanaugh added the Fixed A PR has been merged for this issue label Aug 7, 2018
@RyanCavanaugh
Copy link
Member

Done. Tracking break at #26262

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants