Skip to content

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

Closed
@psnider

Description

@psnider

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:

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions