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

type guard with --strictNullChecks is respected, but then not in a callback scope: TS2345 #22120

Closed
psnider opened this issue Feb 22, 2018 · 2 comments · Fixed by #56908
Closed
Labels
Duplicate An existing issue was already created

Comments

@psnider
Copy link

psnider commented Feb 22, 2018

TypeScript Version:
When using --strictNullChecks with any of these versions:

  • 2.0
  • 2.7.2
  • 2.8.0-dev.20180222 (typescript@next)

Search Terms:

  • TS2345
  • type guard
  • strictNullChecks

Code

in a file tsc-bug.ts:

function asString(): string | undefined {
    return undefined
}

function g(a: string) {
    return
}

function f() {
    let a = asString()   // intellisense correctly shows a is of type string | undefined
    if (a) {    // more explicit guard also fails: if (typeof a === "string")
        let ar = [1,2,3]
        g(a)   // after the type guard "if (a)", intellisense correctly shows a is of type string
        ar.forEach((x) => {
            // tsc 2.7.2 outputs: error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
            // also tsc 2.0 and 2.8.0-dev.20180222
            g(a)   // ERROR: intellisense incorrectly shows a is of type string | undefined
        })
    }
}

Expected behavior:
When using the compiler option: --strictNullChecks

Expect second call of g(a) to be treated the same as the first call.
Both are in the same scope.

Actual behavior:
Second call to g(a) somehow loses track of the type restriction imposed by the guard.
The compiler issues this error:

tsc-bug.ts(18,15): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.

Playground Link:
NOTE: this link doesn't include the --strictNullChecks option, so be sure to set if from the Options button:
http://www.typescriptlang.org/play/#src=function%20asString()%3A%20string%20%7C%20undefined%20%7B%0D%0A%20%20%20%20return%20undefined%0D%0A%7D%0D%0A%0D%0Afunction%20g(a%3A%20string)%20%7B%0D%0A%20%20%20%20return%0D%0A%7D%0D%0A%0D%0Afunction%20f()%20%7B%0D%0A%20%20%20%20let%20a%20%3D%20asString()%20%20%20%2F%2F%20intellisense%20correctly%20shows%20a%20is%20of%20type%20string%20%7C%20undefined%0D%0A%20%20%20%20if%20(a)%20%7B%20%20%20%20%2F%2F%20more%20explicit%20guard%20also%20fails%3A%20if%20(typeof%20a%20%3D%3D%3D%20%22string%22)%0D%0A%20%20%20%20%20%20%20%20let%20ar%20%3D%20%5B1%2C2%2C3%5D%0D%0A%20%20%20%20%20%20%20%20g(a)%20%20%20%2F%2F%20after%20the%20type%20guard%20%22if%20(a)%22%2C%20intellisense%20correctly%20shows%20a%20is%20of%20type%20string%0D%0A%20%20%20%20%20%20%20%20ar.forEach((x)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20tsc%202.7.2%20outputs%3A%20error%20TS2345%3A%20Argument%20of%20type%20'string%20%7C%20undefined'%20is%20not%20assignable%20to%20parameter%20of%20type%20'string'.%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20also%20tsc%202.0%20and%202.8.0-dev.20180222%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20g(a)%20%20%20%2F%2F%20ERROR%3A%20intellisense%20incorrectly%20shows%20a%20is%20of%20type%20string%20%7C%20undefined%0D%0A%20%20%20%20%20%20%20%20%7D)%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A

Related Issues:

@ghost
Copy link

ghost commented Feb 22, 2018

Duplicate of #9998
a is a mutable variable, so we're pessimistic in a callback because it may have been changed by then. Since you don't seem to actually be mutating these variables, consider using const instead of let.

@ghost ghost added the Duplicate An existing issue was already created label Feb 22, 2018
@psnider
Copy link
Author

psnider commented Feb 22, 2018

Sorry, I didn't find #9998 in my search.
After reading this discussion, the idea of pessimistic analysis is clear.

So I think that I should assume pessimistic analysis for now, even if there is no path for modifying a variable.

And your suggestion of const allowed me to get past the compiler error.

@psnider psnider closed this as completed Feb 23, 2018
@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant