Skip to content

Bug Report: Type narrowing not working as expected #912

Closed
@antonio-ivanovski

Description

@antonio-ivanovski

Expected Behavior:

When using type guards like Array.isArray or truthiness checks in an if block, the type of the variable within that block should be narrowed down to the more specific type.

For Array.isArray(foo):

const foo: string | string[] = 'foo'; // or ['foo']
if (Array.isArray(foo)) {
    // foo should be inferred as string[]
    foo; 
}

For truthiness check on bar:

const bar: string | undefined = 'bar'; // or undefined
if (bar) {
    // bar should be inferred as string
    bar;
}

Actual Behavior:

The type of the variable inside the if block is not being narrowed correctly.

For Array.isArray(foo):

const foo: string | string[] = 'foo'; // or string[]
if (Array.isArray(foo)) {
    // foo is inferred as string | string[]
    foo; 
}

The type of foo remains string | string[] inside the if block, even after the Array.isArray(foo) check.

For truthiness check on bar:

const bar: string | undefined = 'bar'; // or undefined
if (bar) {
    // bar is inferred as string | undefined
    bar.charAt(0); // Error: Object is possibly 'undefined'.
}

The type of bar remains string | undefined inside the if block, even after the truthiness check. This can lead to unnecessary errors or require explicit type assertions.

Image Image

Additional Context:

@typescript/native-preview: "7.0.0-dev.20250522.2"
TypeScript (Native Preview): 0.20250522.2

Activity

DanielRosenwasser

DanielRosenwasser commented on May 22, 2025

@DanielRosenwasser
Member

I think this is a bug more in quick info than in narrowing itself - you can tell because an error is reported on the following:

function f(foo: string | string[]) {
    if (Array.isArray(foo)) {
        let x: string = foo; // error

        let y = foo; // hovering on 'y' shows 'string[]'
    }
}

Quick info is currently in development so I guess it's currently only showing the declared type

antonio-ivanovski

antonio-ivanovski commented on May 22, 2025

@antonio-ivanovski
Author

I think this is a bug more in quick info than in narrowing itself - you can tell because an error is reported on the following:

function f(foo: string | string[]) {
    if (Array.isArray(foo)) {
        let x: string = foo; // error

        let y = foo; // hovering on 'y' shows 'string[]'
    }
}

Quick info is currently in development so I guess it's currently only showing the declared type

Haven't checked the particular case you mentioned, but in the case with string | undefined, I was not getting an error in VS Code when I was trying to access property on potentially undefined property. Not sure if this also falls under the category of quick info.

DanielRosenwasser

DanielRosenwasser commented on May 22, 2025

@DanielRosenwasser
Member

Is it possible you were running in a file without --strict on?

Image

antonio-ivanovski

antonio-ivanovski commented on May 22, 2025

@antonio-ivanovski
Author

Is it possible you were running in a file without --strict on?

Image

Will recheck this tomorrow first thing in the morning. Thanks for taking a look so far.

antonio-ivanovski

antonio-ivanovski commented on May 23, 2025

@antonio-ivanovski
Author

Tested again and it seems that only the quick info in vs code is showing invalid type, the actual type under the hood is correct.

Image Image
self-assigned this
on May 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @DanielRosenwasser@antonio-ivanovski@ahejlsberg

    Issue actions

      Bug Report: Type narrowing not working as expected · Issue #912 · microsoft/typescript-go