Skip to content

“This condition will always return true” is, in fact, false #61531

Closed as duplicate

Description

🔎 Search Terms

This condition will always return true since this 'Promise' is always defined.

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=4.3.5#code/DYUwLgBATiDOCuwwC4IAUoHsC2BLWIAPAIYB2AngHwQA+EpiwEAvPSAO7pZ4EAUMsTMABuIFtQDeAKAiyIBMABVc2EJnhhevAJTiI0uYehxEkVg2DAZR2QKGjeF4NuuyAvgBoIARgAMvlzcXKWJYclIAYwgAM3hIsFxMUmg4nX1XCFxoiH4TJF0DGwhidmJcSAFTDIzDLJzK-PSiowikwVAAOmBMAHNeAHIwKA0AC3J+l2a3CBBgAibmuVbSdpAu3oHo4jmQccmitwzDw6lh0h0gA

💻 Code

let result: Promise<any> | null = new Promise(resolve => {
    setTimeout(() => {
        result = null
        resolve(null)
    }, 100)
})

async function run() {
    if (result) {
        await result
    
        if (result) {
            console.log('truthy')
        } else {
            console.log('falsey')
        }
    }
}

run()

🙁 Actual behavior

TS throws an error on line 12 which it shouldn't be throwing:

This condition will always return true since this 'Promise' is always defined.(2801)
input.tsx(12, 13): Did you forget to use 'await'?

🙂 Expected behavior

TS should not throw this error on line 12:

This condition will always return true since this 'Promise' is always defined.

It's making an opinion about a value at runtime that it doesn't have adequate context to adjudicate.

Additional information about the issue

That broader scope conditional on line 9 is narrowing the result type down from Promise<any> | null to Promise<any>, but then the check on line 12 is failing to account for the fact that result could get its value reassigned in virtue of the await on line 10. That await should cause the result type to expand back to the original Promise<any> | null, and make subsequent truthy checks allowable without type errors.

Activity

  1. MartinJohns commented on Apr 4, 2025

    @MartinJohns
    Contributor
  2. martynchamberlin commented on Apr 4, 2025

    @martynchamberlin
    Author

    Ah, ok. Thanks, will close as duplicate. I saw that template but didn't initially think it fit. Reading it in full though I see what you're saying. Closing this as duplicate. Sorry for your time! Thanks.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions