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

Incorrect "did you mean to call" error issued for invoked class property #38161

Closed
RyanCavanaugh opened this issue Apr 24, 2020 · 5 comments · Fixed by #38163
Closed

Incorrect "did you mean to call" error issued for invoked class property #38161

RyanCavanaugh opened this issue Apr 24, 2020 · 5 comments · Fixed by #38163
Assignees
Labels
Bug A bug in TypeScript

Comments

@RyanCavanaugh
Copy link
Member

TypeScript Version: nightly

Search Terms: "did you mean to call"

Code

declare const variable: () => void;
class Foo {
  method!: (() => void);

  f() {
    // Error (incorrect)
    if (this.method) {
      this.method();
    }

    // OK (correct)
    if (variable) {
      variable();
    }
  }

}

Expected behavior: No error

Actual behavior: Error: This condition will always return true; did you mean to call it instead?

Playground Link: Linky

Related Issues: Feature introduced at PR #37152

@decherneyge
Copy link

im not 100% sure this is the same issue but I thought I would check here first before opening a separate issue.

This image is from the typescript playground. Im adding it to show that the compiler is barking at the null check if/when the property is not used within the block but not when it is used which seems inconsistent. The error in both places shown with a red underline is "This condition will always return true since the function is always defined. Did you mean to call it instead?(2774)"
image

image

Code:

class Widget {
    public refresh: (() => void);
    constructor() {
        this.refresh = () => { };
    }
}

class Main{

    public widgets: Array<Widget> = [];
    public $timeout: any;

    constructor() {

        const filterable: Array<Widget> = this.widgets.filter((x) => {
            //error here
            if (x.refresh) {
                //x.refresh();
            }
            //no error here
            if (x.refresh) {
                x.refresh();
            }
        });
        
    }

    private refreshWidget(w: Widget) {
        //error here
        if (w.refresh) {
            this.$timeout(() => {
                //w.refresh();
             });
        }
        //no error here
        if (w.refresh) {
            this.$timeout(() => {
                w.refresh();
             });
        }

    }

}
 

@RyanCavanaugh
Copy link
Member Author

@decherneyge that is precisely the intended behavior

@decherneyge
Copy link

@RyanCavanaugh oh ok. Thanks for the reply! Why is it the intended behavior?

@RyanCavanaugh
Copy link
Member Author

@decherneyge See discussion in #32802 and linked issues from there

@luryson
Copy link

luryson commented Nov 17, 2021

    interface A {
        a: () => boolean;
    }

    class AImpl implements A {
        public a(): boolean {
            return true;
        }
    }

    it('should fail', function () {
        const aImpl = new AImpl();
        if (aImpl.a) { // TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
            console.log("always true");
        }
    });

    it('why success', function () {
        const aImpl = new AImpl();
        if (!aImpl.a) { // nothing happens here
            console.log('always false');
        }
    });

just wondering why !aIpl.a not barking TS2774

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants