Skip to content

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

Closed

Description

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

Activity

  1. decherneyge commented on Jun 17, 2020

    @decherneyge

    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();
                 });
            }
    
        }
    
    }
     
    
  2. RyanCavanaugh commented on Jun 17, 2020

    @RyanCavanaugh
    MemberAuthor

    George DeCherney (@decherneyge) that is precisely the intended behavior

  3. decherneyge commented on Jun 17, 2020

    @decherneyge

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

  4. RyanCavanaugh commented on Jun 17, 2020

    @RyanCavanaugh
    MemberAuthor

    George DeCherney (@decherneyge) See discussion in #32802 and linked issues from there

  5. luryson commented on Nov 17, 2021

    @luryson
        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

  6. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions