The Wayback Machine - https://web.archive.org/web/20230402023541/http://github.com/microsoft/TypeScript/issues/35584
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

Uncalled function checks only works with single conditional #35584

Closed
mjbvz opened this issue Dec 9, 2019 · 14 comments · Fixed by #42835
Closed

Uncalled function checks only works with single conditional #35584

mjbvz opened this issue Dec 9, 2019 · 14 comments · Fixed by #42835
Labels
Experimentation Needed Someone needs to try this out to see what happens Good First Issue Well scoped, documented and has the green light Help Wanted You can do this PursuitFellowship Help wanted from Pursuit fellowship; others please avoid until Dec 19 Suggestion An idea for TypeScript
Milestone

Comments

@mjbvz
Copy link
Contributor

mjbvz commented Dec 9, 2019

TypeScript Version: 3.8.0-dev.20191207

Search Terms:

Code
With strict null checks enabled:

import * as fs from 'fs';

fs.stat('/path/to/file', function(err, stats) {
    if (stats.isFile || stats.isDirectory) {

    }
});

Expected behavior:
Accesses to isFile and isDirectory are reported as errors since these are actually functions

Actual behavior:
No errors.

Errors are only reported when there is a single conditional

Playground Link:

Related Issues:

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Dec 9, 2019
@RyanCavanaugh
Copy link
Member

This is the intended scoping of the check to reduce over-reported errors.

@clarkio
Copy link

clarkio commented Dec 9, 2019

@RyanCavanaugh I can definitely appreciate the reduction in over-reported errors but do you think not having any error at all seems to defeat the purpose? Could there be a way to mention it once for a particular block of code?

@RyanCavanaugh
Copy link
Member

We don't have "Just so you know" warnings and don't intend to add them

@clarkio
Copy link

clarkio commented Dec 9, 2019

I think I may be miscommunicating the scenario or misunderstanding your perspective. I'm hoping to receive the error for the one instance even if there are other conditionals.

For example here we accidentally don't call isDirectory as a function while having some other conditional with it.

import * as fs from 'fs';

fs.stat('/path/to/file', function(err, stats) {
    if (stats.isDirectory && !err) {

    }
});

At the moment if we were to do this the error around stats.isDirectory is not reported at all but if we remove the !err conditional it will report as expected.

Do you think it should still be reported in this scenario?

@DanielRosenwasser
Copy link
Member

This is the intended scoping of the check to reduce over-reported errors.

I may have missed any checks for whether this comes up in conditionals, &&, and || - did we see too many problems on those? My hunch is that that'd be nothing but goodness.

@RyanCavanaugh
Copy link
Member

We can try expanding the set of things checked and see what comes up.

@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@DanielRosenwasser DanielRosenwasser added Experimentation Needed Someone needs to try this out to see what happens Good First Issue Well scoped, documented and has the green light Help Wanted You can do this and removed Working as Intended The behavior described is the intended behavior; this is not a bug labels Dec 13, 2019
@DanielRosenwasser DanielRosenwasser added the Suggestion An idea for TypeScript label Dec 13, 2019
@DanielRosenwasser DanielRosenwasser added this to the Backlog milestone Dec 13, 2019
@dragomirtitian
Copy link
Contributor

@DanielRosenwasser How deep do we want to go here? Any sort of arbitrary expression with boolean operators should be ok ? I think the interesting bit is when the condition both checks and uses the function:

interface StatsBase<T> {
    isDirectory(): boolean;
    time: number
}

function A(err: any, stats: StatsBase<any>) {
    if (stats.isDirectory || stats.isDirectory()) { // should be error ?
        
    }
}

function B(err: any, stats: StatsBase<any>) {
    if (stats.isDirectory && stats.isDirectory()) { // should be ok 
    }
}


function C(err: any, stats: StatsBase<any>) {
    if (!stats.isDirectory || stats.isDirectory()) { // should be ok 
    }
}

Playground Link

@nityatammana
Copy link

Can @mshivaku99 and I work on this (we have a class assignment to help fix a bug in an open-source project)

@sandersn sandersn added the PursuitFellowship Help wanted from Pursuit fellowship; others please avoid until Dec 19 label Sep 18, 2020
@ghost
Copy link

ghost commented Oct 5, 2020

@sandersn
@DanielRosenwasser is it decided if this issue needs to be resolved?

I am doing open-source for this week and would like to help resolve good-first-issue/GraceHopperOSD's issues

@sandersn
Copy link
Member

sandersn commented Oct 5, 2020

@mykolao-wix yep anything in a milestone (such as Backlog) has been accepted. In this case, Experimentation Needed+Suggestion means that the proposed solution might not be workable, but we want to find out by looking at a real implementation.

@mkloouo
Copy link

mkloouo commented Oct 6, 2020

@sandersn is there anyone I can contact to ask src/compiler/checker.ts API questions?

@evmar
Copy link
Contributor

evmar commented Jan 28, 2021

We had a variant of this come up at Google in code like

if (!foo.hasBar) {  // oops, forgot to call the function
  ...
} else {
  // assume foo.hasBar is true
}

I think the broader fix might be something around "expression is always true" when you do a boolean check on a non-optional method.

Playground repro

declare function isFoo(): boolean;

if (isFoo) {
    // expected error, got error
}
if (!isFoo) {
    // expected error, got no error
}

@jonhue
Copy link
Contributor

jonhue commented Feb 17, 2021

Just opened a pull request (#42835) that attempts to address the two problems mentioned in this thread. Feel free to check it out 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Experimentation Needed Someone needs to try this out to see what happens Good First Issue Well scoped, documented and has the green light Help Wanted You can do this PursuitFellowship Help wanted from Pursuit fellowship; others please avoid until Dec 19 Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.